From 4f94e9cade3abe0a382a72b0760506fc9ea0f2d1 Mon Sep 17 00:00:00 2001 From: lkoester Date: Fri, 19 Apr 2024 17:11:38 +0200 Subject: [PATCH 1/7] fixed action tests --- Cargo.lock | 4 +-- src/handlers/camera.rs | 57 +++++++++++++++++++++++++++++++++++++++--- src/pus/action.rs | 6 ++--- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8bfd1c1..55bea81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,9 +593,9 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "satrs" -version = "0.2.0-rc.1" +version = "0.2.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6f3286d35464fdc75dc846b663aaad4a81437a50e623053b1b4d481d782cd0" +checksum = "6aa9241e4d6cb0cc395927cfe653d8bc4a9cb6b2c27f28fec713d5e6ceb0ba23" dependencies = [ "bus", "cobs", diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index d0eae69..629bbd2 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -114,7 +114,7 @@ impl TryFrom for CameraActionIds { // TODO what happens if limits are exceded #[allow(non_snake_case)] -#[derive(Serialize, Deserialize, new)] +#[derive(Debug, Serialize, Deserialize, new)] pub struct CameraPictureParameters { pub R: u8, pub G: u8, @@ -277,8 +277,59 @@ impl IMS100BatchHandler { #[cfg(test)] mod tests { + use std::sync::mpsc; + use std::sync::mpsc::{Receiver, Sender}; + use satrs::action::{ActionRequest, ActionRequestVariant}; + use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; + use satrs::tmtc::PacketAsVec; + use ops_sat_rs::TimeStampHelper; + use crate::handlers::camera::{CameraActionIds, CameraPictureParameters, DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, IMS100BatchHandler}; + use crate::requests::CompositeRequest; + + fn create_handler() -> (IMS100BatchHandler, Sender>, Receiver) { + let id = UniqueApidTargetId::new(1,1); + let (req_tx,req_rx) = mpsc::channel(); + let (tm_tx, tm_rx) = mpsc::channel(); + let time_helper = TimeStampHelper::default(); + let mut cam_handler: IMS100BatchHandler = IMS100BatchHandler::new(id, req_rx, tm_tx, time_helper); + (cam_handler, req_tx, tm_rx) + } + #[test] - fn test_crc() { - // TODO + fn command_line_execution() { + let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + cam_handler.take_picture(DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); + } + + #[test] + fn serialize_and_deserialize_command() { + let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + + let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); + println!("{}", data); + let param: CameraPictureParameters = serde_json::from_str(&data).unwrap(); + println!("{:?}", param); + } + + #[test] + fn test_action_req() { + let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + + let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); + let req = ActionRequest::new(CameraActionIds::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec())); + + cam_handler.handle_action_request(&MessageMetadata::new(1,1),&req).unwrap(); + } + + #[test] + fn test_action_req_channel() { + let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + + let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); + let req = ActionRequest::new(CameraActionIds::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec())); + let req = CompositeRequest::Action(req); + req_tx.send(GenericMessage::new(MessageMetadata::new(1,1), req)).unwrap(); + + cam_handler.periodic_operation(); } } \ No newline at end of file diff --git a/src/pus/action.rs b/src/pus/action.rs index cd2472f..f81d069 100644 --- a/src/pus/action.rs +++ b/src/pus/action.rs @@ -275,7 +275,7 @@ mod tests { use satrs::pus::test_util::{ TEST_APID, TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1, }; - use satrs::pus::verification; + use satrs::pus::{TcInMemory, verification}; use satrs::pus::verification::test_util::TestVerificationReporter; use satrs::request::MessageMetadata; use satrs::ComponentId; @@ -429,7 +429,7 @@ mod tests { .verif_reporter() .check_next_is_acceptance_success(id, accepted_token.request_id()); self.pus_packet_tx - .send(EcssTcAndToken::new(tc.to_vec().unwrap(), accepted_token)) + .send(EcssTcAndToken::new(TcInMemory::Vec(PacketAsVec::new(self.service.service_helper.id(), tc.to_vec().unwrap().into())), accepted_token)) .unwrap(); } } @@ -713,4 +713,4 @@ mod tests { tmtc_err::REQUEST_TIMEOUT.raw() as u64, ); } -} +} \ No newline at end of file From 0f391c2087a5b37feae604ee33f7b9aa0fe5ffe9 Mon Sep 17 00:00:00 2001 From: lkoester Date: Fri, 19 Apr 2024 22:05:57 +0200 Subject: [PATCH 2/7] some minor cleaning up plus initial image file handling --- src/config.rs | 3 ++ src/handlers/camera.rs | 108 ++++++++++++++++++++++++++++++----------- src/lib.rs | 1 + src/main.rs | 40 ++++++++++++++- src/pus/action.rs | 12 +++-- 5 files changed, 131 insertions(+), 33 deletions(-) diff --git a/src/config.rs b/src/config.rs index 4ee0a0e..3ebde60 100644 --- a/src/config.rs +++ b/src/config.rs @@ -115,6 +115,7 @@ pub mod components { UdpServer = 7, TcpServer = 8, TcpSppClient = 9, + CameraHandler = 10, } pub const CONTROLLER_ID: UniqueApidTargetId = @@ -137,6 +138,8 @@ pub mod components { UniqueApidTargetId::new(EXPERIMENT_APID, UniqueId::TcpServer as u32); pub const TCP_SPP_CLIENT: UniqueApidTargetId = UniqueApidTargetId::new(EXPERIMENT_APID, UniqueId::TcpSppClient as u32); + pub const CAMERA_HANDLER: UniqueApidTargetId = + UniqueApidTargetId::new(EXPERIMENT_APID, UniqueId::CameraHandler as u32); } pub mod tasks { diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index 629bbd2..54e0b75 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -24,7 +24,6 @@ /// v Y /// /// see also https://opssat1.esoc.esa.int/dmsf/files/6/view - use crate::requests::CompositeRequest; use derive_new::new; use log::debug; @@ -37,6 +36,7 @@ use serde::{Deserialize, Serialize}; use std::io::Error; use std::process::Command; use std::sync::mpsc; +use satrs::pus::action::ActionReplyPus; const DEFAULT_SINGLE_CAM_PARAMS: CameraPictureParameters = CameraPictureParameters { R: 8, @@ -78,6 +78,10 @@ const BALANCED_SINGLE_FLATSAT_CAM_PARAMS: CameraPictureParameters = CameraPictur W: 1000, }; +// TODO copy as action +// TODO ls -l via cfdp +// TODO howto downlink + #[derive(Debug)] pub enum CameraActionIds { DefaultSingle = 1, @@ -126,19 +130,36 @@ pub struct CameraPictureParameters { } #[allow(dead_code)] -#[derive(new)] +#[derive(Debug)] pub struct IMS100BatchHandler { id: UniqueApidTargetId, // mode_interface: MpscModeLeafInterface, - composite_request_receiver: mpsc::Receiver>, + composite_request_rx: mpsc::Receiver>, // hk_reply_sender: mpsc::Sender>, - tm_sender: mpsc::Sender, + tm_tx: mpsc::Sender, + action_reply_tx: mpsc::Sender>, stamp_helper: TimeStampHelper, } #[allow(non_snake_case)] #[allow(dead_code)] impl IMS100BatchHandler { + pub fn new( + id: UniqueApidTargetId, + composite_request_rx: mpsc::Receiver>, + tm_tx: mpsc::Sender, + action_reply_tx: mpsc::Sender>, + stamp_helper: TimeStampHelper, + ) -> Self { + Self { + id, + composite_request_rx, + tm_tx, + action_reply_tx, + stamp_helper, + } + } + pub fn periodic_operation(&mut self) { self.stamp_helper.update_from_now(); // Handle requests. @@ -148,13 +169,13 @@ impl IMS100BatchHandler { pub fn handle_composite_requests(&mut self) { loop { - match self.composite_request_receiver.try_recv() { + match self.composite_request_rx.try_recv() { Ok(ref msg) => match &msg.message { CompositeRequest::Hk(hk_request) => { self.handle_hk_request(&msg.requestor_info, hk_request); } CompositeRequest::Action(action_request) => { - self.handle_action_request(&msg.requestor_info, action_request); + self.handle_action_request(&msg.requestor_info, action_request).unwrap(); } }, Err(_) => {} @@ -236,6 +257,21 @@ impl IMS100BatchHandler { Ok(()) } + pub fn list_current_images(&self) -> std::io::Result> { + let output = Command::new("ls").arg("-l") + .arg("*.png") + .output()?; + + if output.status.success() { + let output_str = String::from_utf8(output.stdout).unwrap(); + let files: Vec = output_str.lines().map(|s| s.to_string()).collect(); + Ok(files) + } + else { + Err(Error::other("Error getting file list.")) + } + } + pub fn take_picture_from_str( &mut self, R: &str, @@ -277,34 +313,40 @@ impl IMS100BatchHandler { #[cfg(test)] mod tests { + use crate::handlers::camera::{ + CameraActionIds, CameraPictureParameters, IMS100BatchHandler, + DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, + }; + use crate::requests::CompositeRequest; + use ops_sat_rs::config::components::CAMERA_HANDLER; + use ops_sat_rs::TimeStampHelper; + use satrs::action::{ActionRequest, ActionRequestVariant}; + use satrs::request::{GenericMessage, MessageMetadata}; + use satrs::tmtc::PacketAsVec; use std::sync::mpsc; use std::sync::mpsc::{Receiver, Sender}; - use satrs::action::{ActionRequest, ActionRequestVariant}; - use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; - use satrs::tmtc::PacketAsVec; - use ops_sat_rs::TimeStampHelper; - use crate::handlers::camera::{CameraActionIds, CameraPictureParameters, DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, IMS100BatchHandler}; - use crate::requests::CompositeRequest; + use satrs::pus::action::ActionReplyPus; - fn create_handler() -> (IMS100BatchHandler, Sender>, Receiver) { - let id = UniqueApidTargetId::new(1,1); - let (req_tx,req_rx) = mpsc::channel(); + fn create_handler() -> (IMS100BatchHandler, Sender>, Receiver, Receiver>) { + let (composite_request_tx, composite_request_rx) = mpsc::channel(); let (tm_tx, tm_rx) = mpsc::channel(); + let (action_reply_tx, action_reply_rx) = mpsc::channel(); let time_helper = TimeStampHelper::default(); - let mut cam_handler: IMS100BatchHandler = IMS100BatchHandler::new(id, req_rx, tm_tx, time_helper); - (cam_handler, req_tx, tm_rx) + let cam_handler: IMS100BatchHandler = + IMS100BatchHandler::new(CAMERA_HANDLER, composite_request_rx, tm_tx, action_reply_tx, time_helper); + (cam_handler, composite_request_tx, tm_rx, action_reply_rx) } #[test] fn command_line_execution() { - let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); - cam_handler.take_picture(DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); + let (mut cam_handler, req_tx, tm_rx, action_reply_rx) = create_handler(); + cam_handler + .take_picture(DEFAULT_SINGLE_FLATSAT_CAM_PARAMS) + .unwrap(); } #[test] fn serialize_and_deserialize_command() { - let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); - let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); println!("{}", data); let param: CameraPictureParameters = serde_json::from_str(&data).unwrap(); @@ -313,23 +355,33 @@ mod tests { #[test] fn test_action_req() { - let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + let (mut cam_handler, req_tx, tm_rx, action_reply_rx) = create_handler(); let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); - let req = ActionRequest::new(CameraActionIds::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec())); + let req = ActionRequest::new( + CameraActionIds::CustomParameters as u32, + ActionRequestVariant::VecData(data.as_bytes().to_vec()), + ); - cam_handler.handle_action_request(&MessageMetadata::new(1,1),&req).unwrap(); + cam_handler + .handle_action_request(&MessageMetadata::new(1, 1), &req) + .unwrap(); } #[test] fn test_action_req_channel() { - let (mut cam_handler, mut req_tx, mut tm_rx) = create_handler(); + let (mut cam_handler, req_tx, tm_rx, action_reply_rx) = create_handler(); let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); - let req = ActionRequest::new(CameraActionIds::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec())); + let req = ActionRequest::new( + CameraActionIds::CustomParameters as u32, + ActionRequestVariant::VecData(data.as_bytes().to_vec()), + ); let req = CompositeRequest::Action(req); - req_tx.send(GenericMessage::new(MessageMetadata::new(1,1), req)).unwrap(); + req_tx + .send(GenericMessage::new(MessageMetadata::new(1, 1), req)) + .unwrap(); cam_handler.periodic_operation(); } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index d637744..014c607 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ use satrs::spacepackets::time::TimeWriter; pub mod config; +#[derive(Debug)] pub struct TimeStampHelper { stamper: CdsTime, time_stamp: [u8; 7], diff --git a/src/main.rs b/src/main.rs index 4a629be..3db7543 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use std::{ }; use log::info; +use ops_sat_rs::config::components::CAMERA_HANDLER; use ops_sat_rs::config::{ components::{CONTROLLER_ID, TCP_SERVER, TCP_SPP_CLIENT, UDP_SERVER}, tasks::{FREQ_MS_CTRL, FREQ_MS_PUS_STACK}, @@ -13,7 +14,9 @@ use ops_sat_rs::config::{ }; use ops_sat_rs::config::{tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, SERVER_PORT}; use satrs::hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer}; +use ops_sat_rs::TimeStampHelper; +use crate::handlers::camera::IMS100BatchHandler; use crate::tmtc::tc_source::TcSourceTaskDynamic; use crate::tmtc::tm_sink::TmFunnelDynamic; use crate::{controller::ExperimentController, pus::test::create_test_service}; @@ -62,12 +65,16 @@ fn main() { // let (pus_mode_reply_tx, pus_mode_reply_rx) = mpsc::channel(); let (controller_composite_tx, controller_composite_rx) = mpsc::channel(); // let (controller_action_reply_tx, controller_action_reply_rx) = mpsc::channel(); + let (camera_composite_tx, camera_composite_rx) = mpsc::channel(); // Some request are targetable. This map is used to retrieve sender handles based on a target ID. let mut request_map = GenericRequestRouter::default(); request_map .composite_router_map .insert(CONTROLLER_ID.id(), controller_composite_tx); + request_map + .composite_router_map + .insert(CAMERA_HANDLER.id(), camera_composite_tx); let pus_router = PusTcMpscRouter { test_tc_sender: pus_test_tx, @@ -161,7 +168,7 @@ fn main() { let mut controller = ExperimentController::new( controller_composite_rx, - pus_action_reply_tx, + pus_action_reply_tx.clone(), stop_signal.clone(), ); @@ -173,6 +180,13 @@ fn main() { ) .expect("creating TCP SPP client failed"); + let timestamp_helper = TimeStampHelper::default(); + let mut camera_handler: IMS100BatchHandler = + IMS100BatchHandler::new(CAMERA_HANDLER, camera_composite_rx, tm_funnel_tx.clone(), pus_action_reply_tx.clone(), timestamp_helper); + + // Main Task Thread Definitions + + // Main Experiment Control Task info!("Starting CTRL task"); let ctrl_stop_signal = stop_signal.clone(); let jh_ctrl_thread = thread::Builder::new() @@ -186,6 +200,7 @@ fn main() { }) .unwrap(); + // TMTC and UDP Task info!("Starting TMTC and UDP task"); let tmtc_stop_signal = stop_signal.clone(); let jh_udp_tmtc = thread::Builder::new() @@ -203,6 +218,7 @@ fn main() { }) .unwrap(); + // TCP Server Task let tcp_server_stop_signal = stop_signal.clone(); info!("Starting TCP server task"); let jh_tcp_server = thread::Builder::new() @@ -218,6 +234,7 @@ fn main() { }) .unwrap(); + // TCP SPP Client Task // We could also move this to the existing TCP server thread, but we would have to adapt // the server code for this so we do not block anymore and we pause manually if both the client // and server are IDLE and have nothing to do.. @@ -236,6 +253,7 @@ fn main() { }) .unwrap(); + // TM Funnel Task info!("Starting TM funnel task"); let funnel_stop_signal = stop_signal.clone(); let jh_tm_funnel = thread::Builder::new() @@ -248,7 +266,8 @@ fn main() { }) .unwrap(); - info!("Starting PUS handlers thread"); + // PUS Handler Task + info!("Starting PUS handlers task"); let pus_stop_signal = stop_signal.clone(); let jh_pus_handler = thread::Builder::new() .name("ops-sat pus".to_string()) @@ -261,6 +280,20 @@ fn main() { }) .unwrap(); + // Camera Handler Task + info!("Starting camera handler task"); + let camera_stop_signal = stop_signal.clone(); + let jh_camera_handler = thread::Builder::new() + .name("ops-sat camera".to_string()) + .spawn(move || loop { + camera_handler.periodic_operation(); + if camera_stop_signal.load(std::sync::atomic::Ordering::Relaxed) { + break; + } + }) + .unwrap(); + + // Join Threads jh_ctrl_thread .join() .expect("Joining Controller thread failed"); @@ -279,4 +312,7 @@ fn main() { jh_pus_handler .join() .expect("Joining PUS handlers thread failed"); + jh_camera_handler + .join() + .expect("Joining camera handler thread failed"); } diff --git a/src/pus/action.rs b/src/pus/action.rs index f81d069..b87aebc 100644 --- a/src/pus/action.rs +++ b/src/pus/action.rs @@ -275,8 +275,8 @@ mod tests { use satrs::pus::test_util::{ TEST_APID, TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1, }; - use satrs::pus::{TcInMemory, verification}; use satrs::pus::verification::test_util::TestVerificationReporter; + use satrs::pus::{verification, TcInMemory}; use satrs::request::MessageMetadata; use satrs::ComponentId; use satrs::{ @@ -429,7 +429,13 @@ mod tests { .verif_reporter() .check_next_is_acceptance_success(id, accepted_token.request_id()); self.pus_packet_tx - .send(EcssTcAndToken::new(TcInMemory::Vec(PacketAsVec::new(self.service.service_helper.id(), tc.to_vec().unwrap().into())), accepted_token)) + .send(EcssTcAndToken::new( + TcInMemory::Vec(PacketAsVec::new( + self.service.service_helper.id(), + tc.to_vec().unwrap().into(), + )), + accepted_token, + )) .unwrap(); } } @@ -713,4 +719,4 @@ mod tests { tmtc_err::REQUEST_TIMEOUT.raw() as u64, ); } -} \ No newline at end of file +} From 028de494e482d142e035be71f04a563bd727466f Mon Sep 17 00:00:00 2001 From: lkoester Date: Mon, 22 Apr 2024 15:47:25 +0200 Subject: [PATCH 3/7] got basic action stuff running, now to make error handling better --- Cargo.lock | 201 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + pytmtc/camera_params.py | 31 ++++++ pytmtc/common.py | 28 +++++- pytmtc/pus_tc.py | 56 +++++++++++ pytmtc/tc_definitions.py | 8 ++ scripts/ims100_testapp | Bin 0 -> 34280 bytes src/config.rs | 11 ++- src/handlers/camera.rs | 54 ++++++----- src/logger.rs | 11 +-- 10 files changed, 362 insertions(+), 39 deletions(-) create mode 100644 pytmtc/camera_params.py create mode 100644 scripts/ims100_testapp diff --git a/Cargo.lock b/Cargo.lock index 55bea81..23f9bab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -304,6 +304,95 @@ dependencies = [ "log", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -326,6 +415,20 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "homedir" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22074da8bba2ef26fc1737ae6c777b5baab5524c2dc403b5c6a76166766ccda5" +dependencies = [ + "cfg-if", + "nix", + "serde", + "widestring", + "windows-sys 0.48.0", + "wmi", +] + [[package]] name = "humantime" version = "2.1.0" @@ -410,6 +513,15 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "mio" version = "0.8.11" @@ -422,6 +534,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -482,6 +607,7 @@ dependencies = [ "derive-new", "env_logger", "fern", + "homedir", "humantime", "lazy_static", "log", @@ -514,6 +640,18 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -693,6 +831,15 @@ dependencies = [ "serde", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "0.6.14" @@ -893,6 +1040,24 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-implement", + "windows-interface", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -902,6 +1067,28 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-implement" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12168c33176773b86799be25e2a2ba07c7aab9968b37541f1094dbd7a60c8946" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "windows-interface" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d8dc32e0095a7eeccebd0e3f09e9509365ecb3fc6ac4d6f5f14a3f6392942d1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1050,6 +1237,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "wmi" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f0a4062ca522aad4705a2948fd4061b3857537990202a8ddd5af21607f79a" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror", + "windows", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 46ab7bf..9626af7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ num_enum = "0.7" serde = "1" serde_json = "1" mio = "0.8" +homedir = "0.2" [dependencies.satrs] version = "0.2.0-rc.3" diff --git a/pytmtc/camera_params.py b/pytmtc/camera_params.py new file mode 100644 index 0000000..2562372 --- /dev/null +++ b/pytmtc/camera_params.py @@ -0,0 +1,31 @@ +import struct +from serde import Model, fields + +from common import EXPERIMENT_APID, UniqueId, make_addressable_id + +class CameraParameters(Model): + R: fields.Int() + G: fields.Int() + B: fields.Int() + N: fields.Int() + P: fields.Bool() + E: fields.Int() + W: fields.Int() + + def serialize_for_uplink(self) -> bytearray: + return self.to_json().encode('utf-8') + +# Example serialization +data = bytearray(make_addressable_id(EXPERIMENT_APID, UniqueId.CameraHandler)) +params = CameraParameters(8, 8, 8, 1, True, 200, 1000) +serialized = params.to_json().encode('utf-8') +byte_string = bytearray(struct.pack('!{}s'.format(len(serialized)), serialized)) +print(byte_string) +print(params.serialize_for_uplink()) +data.extend(params.serialize_for_uplink()) +print(data) + +# Example deserialization +data = '{"R": 100, "G": 150, "B": 200, "N": 3, "P": true, "E": 10, "W": 20}' +deserialized_params = CameraParameters.from_json(data) +print(deserialized_params) diff --git a/pytmtc/common.py b/pytmtc/common.py index 56b469f..b8a98dc 100644 --- a/pytmtc/common.py +++ b/pytmtc/common.py @@ -3,13 +3,29 @@ from __future__ import annotations import dataclasses import enum import struct - +from serde import Model, fields EXPERIMENT_ID = 278 EXPERIMENT_APID = 1024 + EXPERIMENT_ID +class UniqueId(enum.IntEnum): + + Controller = 0 + PusEventManagement = 1 + PusRouting = 2 + PusTest = 3 + PusAction = 4 + PusMode = 5 + PusHk = 6 + UdpServer = 7 + TcpServer = 8 + TcpSppClient = 9 + CameraHandler = 10 + + class EventSeverity(enum.IntEnum): + INFO = 0 LOW = 1 MEDIUM = 2 @@ -43,6 +59,12 @@ class AcsHkIds(enum.IntEnum): def make_addressable_id(target_id: int, unique_id: int) -> bytes: - byte_string = bytearray(struct.pack("!I", target_id)) - byte_string.extend(struct.pack("!I", unique_id)) + byte_string = bytearray(struct.pack("!I", unique_id)) + # byte_string = bytearray(struct.pack("!I", target_id)) + # byte_string.extend(struct.pack("!I", unique_id)) return byte_string + +def make_addressable_id_with_action_id(unique_id: int, action_id: int) -> bytes: + byte_string = bytearray(struct.pack("!I", unique_id)) + byte_string.extend(struct.pack("!I", action_id)) + return byte_string \ No newline at end of file diff --git a/pytmtc/pus_tc.py b/pytmtc/pus_tc.py index 3a8e83d..136d311 100644 --- a/pytmtc/pus_tc.py +++ b/pytmtc/pus_tc.py @@ -9,6 +9,10 @@ from tmtccmd.pus.tc.s200_fsfw_mode import Mode from tmtccmd.tmtc import DefaultPusQueueHelper from tmtccmd.pus.s11_tc_sched import create_time_tagged_cmd from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice +from serde import Model, fields + +from camera_params import CameraParameters +from common import EXPERIMENT_APID, UniqueId, make_addressable_id, make_addressable_id_with_action_id _LOGGER = logging.getLogger(__name__) @@ -65,6 +69,38 @@ def create_cmd_definition_tree() -> CmdTreeNode: ) root_node.add_child(scheduler_node) + action_node = CmdTreeNode("action", "Action Node") + cam_node = CmdTreeNode( + "take_image", "Take Image with IMS Imager" + ) + cam_node.add_child( + CmdTreeNode( + "default_single", "Default Single Image Camera Parameters" + ) + ) + cam_node.add_child( + CmdTreeNode( + "balanced_single", "Balanced Single Image Camera Parameters" + ) + ) + cam_node.add_child( + CmdTreeNode( + "default_single_flatsat", "Default Single Image Camera Parameters for use on FlatSat" + ) + ) + cam_node.add_child( + CmdTreeNode( + "balanced_single_flatsat", "Balanced Single Image Camera Parameters for use on FlatSat" + ) + ) + cam_node.add_child( + CmdTreeNode( + "custom_params", "Custom Camera Parameters as specified from file" + ) + ) + action_node.add_child(cam_node) + root_node.add_child(action_node) + return root_node @@ -97,6 +133,26 @@ def pack_pus_telecommands(q: DefaultPusQueueHelper, cmd_path: str): ) if cmd_path_list[0] == "acs": assert len(cmd_path_list) >= 2 + if cmd_path_list[0] == "action": + assert len(cmd_path_list)>= 2 + if cmd_path_list[1] == "take_image": + assert len(cmd_path_list)>= 3 + q.add_log_cmd("Sending PUS take image action request with " + cmd_path_list[2] + " params.") + if cmd_path_list[2] == "default_single": + data = make_addressable_id_with_action_id(UniqueId.CameraHandler, 1) + if cmd_path_list[2] == "balanced_single": + data = make_addressable_id_with_action_id(UniqueId.CameraHandler, 2) + if cmd_path_list[2] == "default_single_flatsat": + data = make_addressable_id_with_action_id(UniqueId.CameraHandler, 3) + if cmd_path_list[2] == "balanced_single_flatsat": + data = make_addressable_id_with_action_id(UniqueId.CameraHandler, 4) + if cmd_path_list[2] == "custom": + data = make_addressable_id_with_action_id(UniqueId.CameraHandler, 5) + params = CameraParameters(8, 8, 8, 1, True, 200, 1000) + bytes = params.serialize_for_uplink() + data.extend(bytes) + print(data.hex(sep=",")) + return q.add_pus_tc(PusTelecommand(service=8, subservice=128, apid=EXPERIMENT_APID, app_data=data)) def handle_set_mode_cmd( diff --git a/pytmtc/tc_definitions.py b/pytmtc/tc_definitions.py index 74fbff8..acd2741 100644 --- a/pytmtc/tc_definitions.py +++ b/pytmtc/tc_definitions.py @@ -35,4 +35,12 @@ def tc_definitions() -> TmtcDefinitionWrapper: info="PUS Service 11 TC Scheduling", op_code_entry=srv_11, ) + srv_8 = OpCodeEntry() + srv_8.add("pic", "Action Request Image") + defs.add_service( + name=CoreServiceList.SERVICE_8, + info="PUS Service 8 Action", + op_code_entry=srv_8, + + ) return defs diff --git a/scripts/ims100_testapp b/scripts/ims100_testapp new file mode 100644 index 0000000000000000000000000000000000000000..956a66bec1ef8a5c9c53f0ad28e7b8f680cb41fd GIT binary patch literal 34280 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%0A}icoybf*CONB0z~CR{clVNSIt&{Y6L; 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 literal 0 HcmV?d00001 diff --git a/src/config.rs b/src/config.rs index 3ebde60..a20e021 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,7 +8,7 @@ use std::net::Ipv4Addr; use std::path::{Path, PathBuf}; pub const STOP_FILE_NAME: &str = "stop-experiment"; -pub const HOME_FOLER_EXPERIMENT: &str = "/home/exp278"; +pub const HOME_FOLDER_EXPERIMENT: &str = "/home/exp278"; pub const LOG_FOLDER: &str = "logs"; pub const OBSW_SERVER_ADDR: Ipv4Addr = Ipv4Addr::UNSPECIFIED; @@ -40,12 +40,13 @@ pub enum GroupId { lazy_static! { pub static ref HOME_PATH: PathBuf = { - let home_path_default = env::var("HOME").expect("HOME env variable not set"); let mut home_path = PathBuf::new(); - home_path.push(if Path::new(HOME_FOLER_EXPERIMENT).exists() { - HOME_FOLER_EXPERIMENT + let mut home_path_default = homedir::get_my_home().expect("Getting home dir from OS failed.").expect("No home dir found."); + + home_path.push(if Path::new(HOME_FOLDER_EXPERIMENT).exists() { + HOME_FOLDER_EXPERIMENT } else { - &home_path_default + home_path_default.to_str().expect("Error converting to string.") }); home_path }; diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index 54e0b75..11d6b20 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -36,7 +36,9 @@ use serde::{Deserialize, Serialize}; use std::io::Error; use std::process::Command; use std::sync::mpsc; -use satrs::pus::action::ActionReplyPus; +use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; + +const IMS_TESTAPP: &str = "scripts/ims100_testapp"; const DEFAULT_SINGLE_CAM_PARAMS: CameraPictureParameters = CameraPictureParameters { R: 8, @@ -83,7 +85,7 @@ const BALANCED_SINGLE_FLATSAT_CAM_PARAMS: CameraPictureParameters = CameraPictur // TODO howto downlink #[derive(Debug)] -pub enum CameraActionIds { +pub enum CameraActionId { DefaultSingle = 1, BalancedSingle = 2, DefaultSingleFlatSat = 3, @@ -91,25 +93,25 @@ pub enum CameraActionIds { CustomParameters = 5, } -impl TryFrom for CameraActionIds { +impl TryFrom for CameraActionId { type Error = (); fn try_from(value: u32) -> Result { match value { - value if value == CameraActionIds::DefaultSingle as u32 => { - Ok(CameraActionIds::DefaultSingle) + value if value == CameraActionId::DefaultSingle as u32 => { + Ok(CameraActionId::DefaultSingle) } - value if value == CameraActionIds::BalancedSingle as u32 => { - Ok(CameraActionIds::BalancedSingle) + value if value == CameraActionId::BalancedSingle as u32 => { + Ok(CameraActionId::BalancedSingle) } - value if value == CameraActionIds::DefaultSingleFlatSat as u32 => { - Ok(CameraActionIds::DefaultSingleFlatSat) + value if value == CameraActionId::DefaultSingleFlatSat as u32 => { + Ok(CameraActionId::DefaultSingleFlatSat) } - value if value == CameraActionIds::BalancedSingleFlatSat as u32 => { - Ok(CameraActionIds::BalancedSingleFlatSat) + value if value == CameraActionId::BalancedSingleFlatSat as u32 => { + Ok(CameraActionId::BalancedSingleFlatSat) } - value if value == CameraActionIds::CustomParameters as u32 => { - Ok(CameraActionIds::CustomParameters) + value if value == CameraActionId::CustomParameters as u32 => { + Ok(CameraActionId::CustomParameters) } _ => Err(()), } @@ -193,15 +195,15 @@ impl IMS100BatchHandler { pub fn handle_action_request( &mut self, - _requestor_info: &MessageMetadata, + requestor_info: &MessageMetadata, action_request: &ActionRequest, ) -> std::io::Result<()> { - let param = match CameraActionIds::try_from(action_request.action_id).unwrap() { - CameraActionIds::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, - CameraActionIds::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, - CameraActionIds::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, - CameraActionIds::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, - CameraActionIds::CustomParameters => match &action_request.variant { + let param = match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") { + CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, + CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, + CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, + CameraActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, + CameraActionId::CustomParameters => match &action_request.variant { ActionRequestVariant::NoData => return Err(Error::other("No Data sent!")), ActionRequestVariant::StoreData(_) => { // let param = serde_json::from_slice() @@ -223,11 +225,13 @@ impl IMS100BatchHandler { _ => return Err(Error::other("Invalid Action Request Variant!")), }, }; - self.take_picture(param) + self.take_picture(param)?; + self.action_reply_tx.send(GenericMessage::new(*requestor_info, ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed))).unwrap(); + Ok(()) } pub fn take_picture(&mut self, param: CameraPictureParameters) -> std::io::Result<()> { - let mut cmd = Command::new("ims100_testapp"); + let mut cmd = Command::new(IMS_TESTAPP); cmd.arg("-R") .arg(¶m.R.to_string()) .arg("-G") @@ -314,7 +318,7 @@ impl IMS100BatchHandler { #[cfg(test)] mod tests { use crate::handlers::camera::{ - CameraActionIds, CameraPictureParameters, IMS100BatchHandler, + CameraActionId, CameraPictureParameters, IMS100BatchHandler, DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, }; use crate::requests::CompositeRequest; @@ -359,7 +363,7 @@ mod tests { let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); let req = ActionRequest::new( - CameraActionIds::CustomParameters as u32, + CameraActionId::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec()), ); @@ -374,7 +378,7 @@ mod tests { let data = serde_json::to_string(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS).unwrap(); let req = ActionRequest::new( - CameraActionIds::CustomParameters as u32, + CameraActionId::CustomParameters as u32, ActionRequestVariant::VecData(data.as_bytes().to_vec()), ); let req = CompositeRequest::Action(req); diff --git a/src/logger.rs b/src/logger.rs index 4df2e97..c9bafc4 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use ops_sat_rs::config::LOG_FOLDER; @@ -6,6 +6,9 @@ pub fn setup_logger() -> Result<(), fern::InitError> { if !Path::new(LOG_FOLDER).exists() && std::fs::create_dir_all(LOG_FOLDER).is_err() { eprintln!("Failed to create log folder '{}'", LOG_FOLDER); } + let mut path_buf = PathBuf::from(LOG_FOLDER); + path_buf.push(format!("output.log")); + println!("{:?}", path_buf); fern::Dispatch::new() .format(move |out, message, record| { out.finish(format_args!( @@ -18,11 +21,7 @@ pub fn setup_logger() -> Result<(), fern::InitError> { }) .level(log::LevelFilter::Debug) .chain(std::io::stdout()) - .chain(fern::log_file(format!( - "{}/output_{}.log", - LOG_FOLDER, - humantime::format_rfc3339_seconds(std::time::SystemTime::now()) - ))?) + .chain(fern::log_file(path_buf.as_os_str())?) .apply()?; Ok(()) } From 88d4384beb3bb54af2e6104bfcd03fe9089338f9 Mon Sep 17 00:00:00 2001 From: lkoester Date: Mon, 22 Apr 2024 16:56:49 +0200 Subject: [PATCH 4/7] this should be good for now --- Cargo.lock | 42 +++++++++++++------------- src/config.rs | 5 ++-- src/handlers/camera.rs | 68 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0a16ca..d468c5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,7 +360,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -834,21 +834,21 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -======= name = "serde_spanned" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ->>>>>>> main +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", ] [[package]] @@ -1114,7 +1114,7 @@ checksum = "12168c33176773b86799be25e2a2ba07c7aab9968b37541f1094dbd7a60c8946" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1125,7 +1125,7 @@ checksum = "9d8dc32e0095a7eeccebd0e3f09e9509365ecb3fc6ac4d6f5f14a3f6392942d1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1277,7 +1277,15 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD +name = "winnow" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +dependencies = [ + "memchr", +] + +[[package]] name = "wmi" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1289,14 +1297,6 @@ dependencies = [ "serde", "thiserror", "windows", -======= -name = "winnow" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" -dependencies = [ - "memchr", ->>>>>>> main ] [[package]] diff --git a/src/config.rs b/src/config.rs index e02650d..dfeea50 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,13 +3,12 @@ use num_enum::{IntoPrimitive, TryFromPrimitive}; use satrs::spacepackets::PacketId; use satrs_mib::res_code::ResultU16Info; use satrs_mib::resultcode; -use std::env; use std::net::Ipv4Addr; use std::path::{Path, PathBuf}; pub const STOP_FILE_NAME: &str = "stop-experiment"; pub const CONFIG_FILE_NAME: &str = "exp278.toml"; -pub const HOME_FOLER_EXPERIMENT: &str = "/home/exp278"; +pub const HOME_FOLDER_EXPERIMENT: &str = "/home/exp278"; pub const LOG_FOLDER: &str = "logs"; pub const OBSW_SERVER_ADDR: Ipv4Addr = Ipv4Addr::UNSPECIFIED; @@ -43,7 +42,7 @@ pub enum GroupId { lazy_static! { pub static ref HOME_PATH: PathBuf = { let mut home_path = PathBuf::new(); - let mut home_path_default = homedir::get_my_home().expect("Getting home dir from OS failed.").expect("No home dir found."); + let home_path_default = homedir::get_my_home().expect("Getting home dir from OS failed.").expect("No home dir found."); home_path.push(if Path::new(HOME_FOLDER_EXPERIMENT).exists() { HOME_FOLDER_EXPERIMENT diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index e93a92c..3fdbb26 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -1,3 +1,5 @@ +use std::fmt; +use std::fmt::Formatter; /// Device handler implementation for the IMS-100 Imager used on the OPS-SAT mission. /// /// from the [OPSSAT Experimenter Wiki](https://opssat1.esoc.esa.int/projects/experimenter-information/wiki/Camera_Introduction): @@ -26,14 +28,13 @@ /// see also https://opssat1.esoc.esa.int/dmsf/files/6/view use crate::requests::CompositeRequest; use derive_new::new; -use log::debug; +use log::{debug, info}; use ops_sat_rs::TimeStampHelper; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::hk::HkRequest; use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; use satrs::tmtc::PacketAsVec; use serde::{Deserialize, Serialize}; -use std::io::Error; use std::process::Command; use std::sync::mpsc; use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; @@ -131,6 +132,48 @@ pub struct CameraPictureParameters { pub W: u32, // wait time between pictures in ms, max: 40000 } +#[derive(Debug)] +#[allow(dead_code)] +pub enum CameraError { + TakeImageError, + NoDataSent, + VariantNotImplemented, + DeserializeError, + ListFileError, + IoError(std::io::Error), +} + +impl From for CameraError { + fn from(value: std::io::Error) -> Self { + Self::IoError(value) + } +} + +impl fmt::Display for CameraError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + CameraError::TakeImageError => { + write!(f, "Error taking image.") + } + CameraError::NoDataSent => { + write!(f, "No data sent.") + } + CameraError::VariantNotImplemented => { + write!(f, "Request variant not implemented.") + } + CameraError::DeserializeError => { + write!(f, "Unable to deserialize parameters.") + } + CameraError::ListFileError => { + write!(f, "Error listing image files.") + } + CameraError::IoError(io_error) => { + write!(f, "{}", io_error) + } + } + } +} + #[allow(dead_code)] #[derive(Debug)] pub struct IMS100BatchHandler { @@ -207,20 +250,18 @@ impl IMS100BatchHandler { &mut self, requestor_info: &MessageMetadata, action_request: &ActionRequest, - ) -> std::io::Result<()> { + ) -> Result<(), CameraError> { let param = match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") { CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, CameraActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, CameraActionId::CustomParameters => match &action_request.variant { - ActionRequestVariant::NoData => return Err(Error::other("No Data sent!")), + ActionRequestVariant::NoData => return Err(CameraError::NoDataSent), ActionRequestVariant::StoreData(_) => { // let param = serde_json::from_slice() // TODO implement non dynamic version - return Err(Error::other( - "Static parameter transfer not implemented yet!", - )); + return Err(CameraError::VariantNotImplemented); } ActionRequestVariant::VecData(data) => { let param: serde_json::Result = @@ -228,11 +269,11 @@ impl IMS100BatchHandler { match param { Ok(param) => param, Err(_) => { - return Err(Error::other("Unable to deserialize parameters")); + return Err(CameraError::DeserializeError); } } } - _ => return Err(Error::other("Invalid Action Request Variant!")), + _ => return Err(CameraError::VariantNotImplemented), }, }; self.take_picture(param)?; @@ -240,7 +281,8 @@ impl IMS100BatchHandler { Ok(()) } - pub fn take_picture(&mut self, param: CameraPictureParameters) -> std::io::Result<()> { + pub fn take_picture(&mut self, param: CameraPictureParameters) -> Result<(), CameraError> { + info!("Taking image!"); let mut cmd = Command::new(IMS_TESTAPP); cmd.arg("-R") .arg(¶m.R.to_string()) @@ -271,7 +313,7 @@ impl IMS100BatchHandler { Ok(()) } - pub fn list_current_images(&self) -> std::io::Result> { + pub fn list_current_images(&self) -> Result, CameraError> { let output = Command::new("ls").arg("-l") .arg("*.png") .output()?; @@ -282,7 +324,7 @@ impl IMS100BatchHandler { Ok(files) } else { - Err(Error::other("Error getting file list.")) + Err(CameraError::ListFileError) } } @@ -295,7 +337,7 @@ impl IMS100BatchHandler { P: &str, E: &str, W: &str, - ) -> std::io::Result<()> { + ) -> Result<(), CameraError> { let mut cmd = Command::new("ims100_testapp"); cmd.arg("-R") .arg(R) From 09bef401c07e62f897eed99a627133b7d4bd9b60 Mon Sep 17 00:00:00 2001 From: lkoester Date: Wed, 24 Apr 2024 16:26:54 +0200 Subject: [PATCH 5/7] added data reply to camera handler, now only missing tmtcpy counterpart --- scripts/ims100_testapp | Bin 34280 -> 0 bytes src/handlers/camera.rs | 28 +++++++++++++++++++++------- src/pus/action.rs | 29 +++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 13 deletions(-) delete mode 100644 scripts/ims100_testapp diff --git a/scripts/ims100_testapp b/scripts/ims100_testapp deleted file mode 100644 index 956a66bec1ef8a5c9c53f0ad28e7b8f680cb41fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34280 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%0A}icoybf*CONB0z~CR{clVNSIt&{Y6L; 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 diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index 3fdbb26..6145649 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -35,11 +35,14 @@ use satrs::hk::HkRequest; use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; use satrs::tmtc::PacketAsVec; use serde::{Deserialize, Serialize}; -use std::process::Command; +use std::process::{Command, Output}; use std::sync::mpsc; use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; +use satrs::pus::EcssTmtcError; +use crate::pus::action::send_data_reply; -const IMS_TESTAPP: &str = "scripts/ims100_testapp"; +// const IMS_TESTAPP: &str = "scripts/ims100_testapp"; +const IMS_TESTAPP: &str = "ims100_testapp"; const DEFAULT_SINGLE_CAM_PARAMS: CameraPictureParameters = CameraPictureParameters { R: 8, @@ -141,6 +144,7 @@ pub enum CameraError { DeserializeError, ListFileError, IoError(std::io::Error), + EcssTmtcError(EcssTmtcError), } impl From for CameraError { @@ -149,6 +153,12 @@ impl From for CameraError { } } +impl From for CameraError { + fn from(value: EcssTmtcError) -> Self { + Self::EcssTmtcError(value) + } +} + impl fmt::Display for CameraError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -170,6 +180,9 @@ impl fmt::Display for CameraError { CameraError::IoError(io_error) => { write!(f, "{}", io_error) } + CameraError::EcssTmtcError(ecss_tmtc_error) => { + write!(f ,"{}", ecss_tmtc_error) + } } } } @@ -276,12 +289,14 @@ impl IMS100BatchHandler { _ => return Err(CameraError::VariantNotImplemented), }, }; - self.take_picture(param)?; + let output = self.take_picture(param)?; + debug!("Sending action reply!"); + send_data_reply(self.id, output.stdout, &self.stamp_helper, &self.tm_tx)?; self.action_reply_tx.send(GenericMessage::new(*requestor_info, ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed))).unwrap(); Ok(()) } - pub fn take_picture(&mut self, param: CameraPictureParameters) -> Result<(), CameraError> { + pub fn take_picture(&mut self, param: CameraPictureParameters) -> Result { info!("Taking image!"); let mut cmd = Command::new(IMS_TESTAPP); cmd.arg("-R") @@ -305,12 +320,11 @@ impl IMS100BatchHandler { .arg(¶m.E.to_string()) .arg("-w") .arg(¶m.W.to_string()); - let output = cmd.output()?; - debug!("{}", String::from_utf8_lossy(&output.stdout)); + debug!("Imager Output: {}", String::from_utf8_lossy(&output.stdout)); - Ok(()) + Ok(output) } pub fn list_current_images(&self) -> Result, CameraError> { diff --git a/src/pus/action.rs b/src/pus/action.rs index 7d597e4..66d86c7 100644 --- a/src/pus/action.rs +++ b/src/pus/action.rs @@ -1,5 +1,4 @@ use log::{error, warn}; -use ops_sat_rs::config::components::PUS_ACTION_SERVICE; use ops_sat_rs::config::tmtc_err; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::params::WritableToBeBytes; @@ -10,17 +9,17 @@ use satrs::pus::verification::{ FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted, VerificationReporter, VerificationReportingProvider, VerificationToken, }; -use satrs::pus::{ - ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, - GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, - PusTcToRequestConverter, -}; +use satrs::pus::{ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, PusTmVariant}; use satrs::request::{GenericMessage, UniqueApidTargetId}; use satrs::spacepackets::ecss::tc::PusTcReader; use satrs::spacepackets::ecss::{EcssEnumU16, PusPacket}; use satrs::tmtc::PacketAsVec; use std::sync::mpsc; use std::time::Duration; +use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; +use satrs::spacepackets::SpHeader; +use ops_sat_rs::config::components::PUS_ACTION_SERVICE; +use ops_sat_rs::TimeStampHelper; use crate::requests::GenericRequestRouter; @@ -29,6 +28,8 @@ use super::{ PusTargetedRequestService, TargetedPusService, }; +pub const DATA_REPLY: u8 = 130; + pub struct ActionReplyHandler { fail_data_buf: [u8; 128], } @@ -270,6 +271,22 @@ impl TargetedPusService for ActionServiceWrapper { } } +pub fn send_data_reply(apid_target: UniqueApidTargetId, reply_data: Vec, stamp_helper: &TimeStampHelper, tm_sender: &TmSender) -> Result<(), EcssTmtcError> { + let sp_header = SpHeader::new_from_apid(apid_target.apid); + let sec_header = PusTmSecondaryHeader::new(8, DATA_REPLY, 0, 0, stamp_helper.stamp()); + let mut data = Vec::new(); + data.extend(apid_target.apid.to_be_bytes()); + data.extend(apid_target.unique_id.to_be_bytes()); + data.extend(reply_data); + let data_reply_tm = PusTmCreator::new( + sp_header, + sec_header, + &data, + true, + ); + tm_sender.send_tm(apid_target.id(), PusTmVariant::Direct(data_reply_tm)) +} + #[cfg(test)] mod tests { use satrs::pus::test_util::{ From 83322ae4155143fadc8c6866f47cc4045f7a14da Mon Sep 17 00:00:00 2001 From: lkoester Date: Wed, 24 Apr 2024 16:43:59 +0200 Subject: [PATCH 6/7] added debug output in action reply handler and tm handling in tmtcpy, ready to merge into main --- pytmtc/pyclient.py | 6 ++++++ src/pus/action.rs | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pytmtc/pyclient.py b/pytmtc/pyclient.py index a02d648..e24b519 100755 --- a/pytmtc/pyclient.py +++ b/pytmtc/pyclient.py @@ -143,6 +143,12 @@ class PusHandler(GenericApidHandlerBase): _LOGGER.info(f"Received event packet. Event: {event_u32}") if event_u32.group_id == 0 and event_u32.unique_id == 0: _LOGGER.info("Received test event") + elif service == 8: + if pus_tm.subservice == 130: + _LOGGER.info(f"Received Action Data Reply TM[8,130]") + reply = pus_tm.source_data + reply = reply[6:] + _LOGGER.info(f"Data Reply Content: " + reply.decode('utf-8')) elif service == 17: tm_packet = Service17Tm.unpack( packet, time_reader=CdsShortTimestamp.empty() diff --git a/src/pus/action.rs b/src/pus/action.rs index 66d86c7..cc618d9 100644 --- a/src/pus/action.rs +++ b/src/pus/action.rs @@ -1,4 +1,4 @@ -use log::{error, warn}; +use log::{debug, error, warn}; use ops_sat_rs::config::tmtc_err; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::params::WritableToBeBytes; @@ -278,6 +278,7 @@ pub fn send_data_reply(apid_target: UniqueApidTargetId, data.extend(apid_target.apid.to_be_bytes()); data.extend(apid_target.unique_id.to_be_bytes()); data.extend(reply_data); + debug!("{}", String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.")); let data_reply_tm = PusTmCreator::new( sp_header, sec_header, From 6f3e14af3b511c5a8a2abf479a32198aac156862 Mon Sep 17 00:00:00 2001 From: lkoester Date: Wed, 24 Apr 2024 16:45:38 +0200 Subject: [PATCH 7/7] fmt and clippy --- src/config.rs | 8 +++- src/handlers/camera.rs | 91 ++++++++++++++++++++++++------------------ src/logger.rs | 2 +- src/main.rs | 11 +++-- src/pus/action.rs | 31 ++++++++------ 5 files changed, 86 insertions(+), 57 deletions(-) diff --git a/src/config.rs b/src/config.rs index dfeea50..05be938 100644 --- a/src/config.rs +++ b/src/config.rs @@ -42,12 +42,16 @@ pub enum GroupId { lazy_static! { pub static ref HOME_PATH: PathBuf = { let mut home_path = PathBuf::new(); - let home_path_default = homedir::get_my_home().expect("Getting home dir from OS failed.").expect("No home dir found."); + let home_path_default = homedir::get_my_home() + .expect("Getting home dir from OS failed.") + .expect("No home dir found."); home_path.push(if Path::new(HOME_FOLDER_EXPERIMENT).exists() { HOME_FOLDER_EXPERIMENT } else { - home_path_default.to_str().expect("Error converting to string.") + home_path_default + .to_str() + .expect("Error converting to string.") }); home_path }; diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index 6145649..ab82668 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -1,5 +1,4 @@ -use std::fmt; -use std::fmt::Formatter; +use crate::pus::action::send_data_reply; /// Device handler implementation for the IMS-100 Imager used on the OPS-SAT mission. /// /// from the [OPSSAT Experimenter Wiki](https://opssat1.esoc.esa.int/projects/experimenter-information/wiki/Camera_Introduction): @@ -32,14 +31,15 @@ use log::{debug, info}; use ops_sat_rs::TimeStampHelper; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::hk::HkRequest; +use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; +use satrs::pus::EcssTmtcError; use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; use satrs::tmtc::PacketAsVec; use serde::{Deserialize, Serialize}; +use std::fmt; +use std::fmt::Formatter; use std::process::{Command, Output}; use std::sync::mpsc; -use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; -use satrs::pus::EcssTmtcError; -use crate::pus::action::send_data_reply; // const IMS_TESTAPP: &str = "scripts/ims100_testapp"; const IMS_TESTAPP: &str = "ims100_testapp"; @@ -181,7 +181,7 @@ impl fmt::Display for CameraError { write!(f, "{}", io_error) } CameraError::EcssTmtcError(ecss_tmtc_error) => { - write!(f ,"{}", ecss_tmtc_error) + write!(f, "{}", ecss_tmtc_error) } } } @@ -264,35 +264,41 @@ impl IMS100BatchHandler { requestor_info: &MessageMetadata, action_request: &ActionRequest, ) -> Result<(), CameraError> { - let param = match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") { - CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, - CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, - CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, - CameraActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, - CameraActionId::CustomParameters => match &action_request.variant { - ActionRequestVariant::NoData => return Err(CameraError::NoDataSent), - ActionRequestVariant::StoreData(_) => { - // let param = serde_json::from_slice() - // TODO implement non dynamic version - return Err(CameraError::VariantNotImplemented); - } - ActionRequestVariant::VecData(data) => { - let param: serde_json::Result = - serde_json::from_slice(data.as_slice()); - match param { - Ok(param) => param, - Err(_) => { - return Err(CameraError::DeserializeError); + let param = + match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") { + CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, + CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, + CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, + CameraActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, + CameraActionId::CustomParameters => match &action_request.variant { + ActionRequestVariant::NoData => return Err(CameraError::NoDataSent), + ActionRequestVariant::StoreData(_) => { + // let param = serde_json::from_slice() + // TODO implement non dynamic version + return Err(CameraError::VariantNotImplemented); + } + ActionRequestVariant::VecData(data) => { + let param: serde_json::Result = + serde_json::from_slice(data.as_slice()); + match param { + Ok(param) => param, + Err(_) => { + return Err(CameraError::DeserializeError); + } } } - } - _ => return Err(CameraError::VariantNotImplemented), - }, - }; + _ => return Err(CameraError::VariantNotImplemented), + }, + }; let output = self.take_picture(param)?; debug!("Sending action reply!"); send_data_reply(self.id, output.stdout, &self.stamp_helper, &self.tm_tx)?; - self.action_reply_tx.send(GenericMessage::new(*requestor_info, ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed))).unwrap(); + self.action_reply_tx + .send(GenericMessage::new( + *requestor_info, + ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed), + )) + .unwrap(); Ok(()) } @@ -328,16 +334,13 @@ impl IMS100BatchHandler { } pub fn list_current_images(&self) -> Result, CameraError> { - let output = Command::new("ls").arg("-l") - .arg("*.png") - .output()?; + let output = Command::new("ls").arg("-l").arg("*.png").output()?; if output.status.success() { let output_str = String::from_utf8(output.stdout).unwrap(); let files: Vec = output_str.lines().map(|s| s.to_string()).collect(); Ok(files) - } - else { + } else { Err(CameraError::ListFileError) } } @@ -391,19 +394,29 @@ mod tests { use ops_sat_rs::config::components::CAMERA_HANDLER; use ops_sat_rs::TimeStampHelper; use satrs::action::{ActionRequest, ActionRequestVariant}; + use satrs::pus::action::ActionReplyPus; use satrs::request::{GenericMessage, MessageMetadata}; use satrs::tmtc::PacketAsVec; use std::sync::mpsc; use std::sync::mpsc::{Receiver, Sender}; - use satrs::pus::action::ActionReplyPus; - fn create_handler() -> (IMS100BatchHandler, Sender>, Receiver, Receiver>) { + fn create_handler() -> ( + IMS100BatchHandler, + Sender>, + Receiver, + Receiver>, + ) { let (composite_request_tx, composite_request_rx) = mpsc::channel(); let (tm_tx, tm_rx) = mpsc::channel(); let (action_reply_tx, action_reply_rx) = mpsc::channel(); let time_helper = TimeStampHelper::default(); - let cam_handler: IMS100BatchHandler = - IMS100BatchHandler::new(CAMERA_HANDLER, composite_request_rx, tm_tx, action_reply_tx, time_helper); + let cam_handler: IMS100BatchHandler = IMS100BatchHandler::new( + CAMERA_HANDLER, + composite_request_rx, + tm_tx, + action_reply_tx, + time_helper, + ); (cam_handler, composite_request_tx, tm_rx, action_reply_rx) } diff --git a/src/logger.rs b/src/logger.rs index c9bafc4..8779c13 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -7,7 +7,7 @@ pub fn setup_logger() -> Result<(), fern::InitError> { eprintln!("Failed to create log folder '{}'", LOG_FOLDER); } let mut path_buf = PathBuf::from(LOG_FOLDER); - path_buf.push(format!("output.log")); + path_buf.push("output.log"); println!("{:?}", path_buf); fern::Dispatch::new() .format(move |out, message, record| { diff --git a/src/main.rs b/src/main.rs index 8119a2b..d516769 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,8 @@ use ops_sat_rs::config::{ VALID_PACKET_ID_LIST, }; use ops_sat_rs::config::{tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, SERVER_PORT}; -use satrs::hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer}; use ops_sat_rs::TimeStampHelper; +use satrs::hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer}; use crate::handlers::camera::IMS100BatchHandler; use crate::pus::{PusTcDistributor, PusTcMpscRouter}; @@ -184,8 +184,13 @@ fn main() { .expect("creating TCP SPP client failed"); let timestamp_helper = TimeStampHelper::default(); - let mut camera_handler: IMS100BatchHandler = - IMS100BatchHandler::new(CAMERA_HANDLER, camera_composite_rx, tm_funnel_tx.clone(), pus_action_reply_tx.clone(), timestamp_helper); + let mut camera_handler: IMS100BatchHandler = IMS100BatchHandler::new( + CAMERA_HANDLER, + camera_composite_rx, + tm_funnel_tx.clone(), + pus_action_reply_tx.clone(), + timestamp_helper, + ); // Main Task Thread Definitions diff --git a/src/pus/action.rs b/src/pus/action.rs index cc618d9..4101e4d 100644 --- a/src/pus/action.rs +++ b/src/pus/action.rs @@ -1,5 +1,7 @@ use log::{debug, error, warn}; +use ops_sat_rs::config::components::PUS_ACTION_SERVICE; use ops_sat_rs::config::tmtc_err; +use ops_sat_rs::TimeStampHelper; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::params::WritableToBeBytes; use satrs::pus::action::{ @@ -9,17 +11,19 @@ use satrs::pus::verification::{ FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted, VerificationReporter, VerificationReportingProvider, VerificationToken, }; -use satrs::pus::{ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, PusTmVariant}; +use satrs::pus::{ + ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, + GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, + PusTcToRequestConverter, PusTmVariant, +}; use satrs::request::{GenericMessage, UniqueApidTargetId}; use satrs::spacepackets::ecss::tc::PusTcReader; +use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; use satrs::spacepackets::ecss::{EcssEnumU16, PusPacket}; +use satrs::spacepackets::SpHeader; use satrs::tmtc::PacketAsVec; use std::sync::mpsc; use std::time::Duration; -use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; -use satrs::spacepackets::SpHeader; -use ops_sat_rs::config::components::PUS_ACTION_SERVICE; -use ops_sat_rs::TimeStampHelper; use crate::requests::GenericRequestRouter; @@ -271,20 +275,23 @@ impl TargetedPusService for ActionServiceWrapper { } } -pub fn send_data_reply(apid_target: UniqueApidTargetId, reply_data: Vec, stamp_helper: &TimeStampHelper, tm_sender: &TmSender) -> Result<(), EcssTmtcError> { +pub fn send_data_reply( + apid_target: UniqueApidTargetId, + reply_data: Vec, + stamp_helper: &TimeStampHelper, + tm_sender: &TmSender, +) -> Result<(), EcssTmtcError> { let sp_header = SpHeader::new_from_apid(apid_target.apid); let sec_header = PusTmSecondaryHeader::new(8, DATA_REPLY, 0, 0, stamp_helper.stamp()); let mut data = Vec::new(); data.extend(apid_target.apid.to_be_bytes()); data.extend(apid_target.unique_id.to_be_bytes()); data.extend(reply_data); - debug!("{}", String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.")); - let data_reply_tm = PusTmCreator::new( - sp_header, - sec_header, - &data, - true, + debug!( + "{}", + String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.") ); + let data_reply_tm = PusTmCreator::new(sp_header, sec_header, &data, true); tm_sender.send_tm(apid_target.id(), PusTmVariant::Direct(data_reply_tm)) }