use the user handler for the first time
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2023-08-11 13:50:06 +02:00
parent f69035a868
commit 8a73a99f26
Signed by: muellerr
GPG Key ID: A649FB78196E3849

View File

@ -5,7 +5,10 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use super::{user::CfdpUser, State, TransactionStep, CRC_32}; use super::{
user::{CfdpUser, MetadataReceivedParams},
State, TransactionId, TransactionStep, CRC_32,
};
use alloc::boxed::Box; use alloc::boxed::Box;
use spacepackets::{ use spacepackets::{
cfdp::{ cfdp::{
@ -27,7 +30,6 @@ pub struct DestinationHandler {
id: UnsignedByteField, id: UnsignedByteField,
step: TransactionStep, step: TransactionStep,
state: State, state: State,
pdu_conf: CommonPduConfig,
transaction_params: TransactionParams, transaction_params: TransactionParams,
packets_to_send_ctx: PacketsToSendContext, packets_to_send_ctx: PacketsToSendContext,
cfdp_user: Box<dyn CfdpUser>, cfdp_user: Box<dyn CfdpUser>,
@ -39,28 +41,46 @@ struct PacketsToSendContext {
directive: Option<FileDirectiveType>, directive: Option<FileDirectiveType>,
} }
struct TransactionParams { #[derive(Debug)]
metadata_params: MetadataGenericParams, struct FileProperties {
src_file_name: [u8; u8::MAX as usize], src_file_name: [u8; u8::MAX as usize],
src_file_name_len: usize, src_file_name_len: usize,
dest_file_name: [u8; u8::MAX as usize], dest_file_name: [u8; u8::MAX as usize],
dest_file_name_len: usize, dest_file_name_len: usize,
dest_path_buf: PathBuf, dest_path_buf: PathBuf,
}
#[derive(Debug)]
struct TransactionParams {
transaction_id: Option<TransactionId>,
metadata_params: MetadataGenericParams,
pdu_conf: CommonPduConfig,
file_properties: FileProperties,
condition_code: ConditionCode, condition_code: ConditionCode,
delivery_code: DeliveryCode, delivery_code: DeliveryCode,
file_status: FileStatus, file_status: FileStatus,
cksum_buf: [u8; 1024], cksum_buf: [u8; 1024],
} }
impl Default for TransactionParams { impl Default for FileProperties {
fn default() -> Self { fn default() -> Self {
Self { Self {
metadata_params: Default::default(),
src_file_name: [0; u8::MAX as usize], src_file_name: [0; u8::MAX as usize],
src_file_name_len: Default::default(), src_file_name_len: Default::default(),
dest_file_name: [0; u8::MAX as usize], dest_file_name: [0; u8::MAX as usize],
dest_file_name_len: Default::default(), dest_file_name_len: Default::default(),
dest_path_buf: Default::default(), dest_path_buf: Default::default(),
}
}
}
impl Default for TransactionParams {
fn default() -> Self {
Self {
transaction_id: None,
metadata_params: Default::default(),
pdu_conf: Default::default(),
file_properties: Default::default(),
condition_code: ConditionCode::NoError, condition_code: ConditionCode::NoError,
delivery_code: DeliveryCode::Incomplete, delivery_code: DeliveryCode::Incomplete,
file_status: FileStatus::Unreported, file_status: FileStatus::Unreported,
@ -108,7 +128,6 @@ impl DestinationHandler {
id: id.into(), id: id.into(),
step: TransactionStep::Idle, step: TransactionStep::Idle,
state: State::Idle, state: State::Idle,
pdu_conf: Default::default(),
transaction_params: Default::default(), transaction_params: Default::default(),
packets_to_send_ctx: Default::default(), packets_to_send_ctx: Default::default(),
cfdp_user, cfdp_user,
@ -154,7 +173,7 @@ impl DestinationHandler {
let directive = self.packets_to_send_ctx.directive.unwrap(); let directive = self.packets_to_send_ctx.directive.unwrap();
let written_size = match directive { let written_size = match directive {
FileDirectiveType::FinishedPdu => { FileDirectiveType::FinishedPdu => {
let pdu_header = PduHeader::new_no_file_data(self.pdu_conf, 0); let pdu_header = PduHeader::new_no_file_data(self.transaction_params.pdu_conf, 0);
let finished_pdu = if self.transaction_params.condition_code let finished_pdu = if self.transaction_params.condition_code
== ConditionCode::NoError == ConditionCode::NoError
|| self.transaction_params.condition_code || self.transaction_params.condition_code
@ -223,16 +242,17 @@ impl DestinationHandler {
if src_name.is_empty() { if src_name.is_empty() {
return Err(DestError::EmptySrcFileField); return Err(DestError::EmptySrcFileField);
} }
self.transaction_params.src_file_name[..src_name.len_value()] self.transaction_params.file_properties.src_file_name[..src_name.len_value()]
.copy_from_slice(src_name.value().unwrap()); .copy_from_slice(src_name.value().unwrap());
self.transaction_params.src_file_name_len = src_name.len_value(); self.transaction_params.file_properties.src_file_name_len = src_name.len_value();
let dest_name = metadata_pdu.dest_file_name(); let dest_name = metadata_pdu.dest_file_name();
if dest_name.is_empty() { if dest_name.is_empty() {
return Err(DestError::EmptyDestFileField); return Err(DestError::EmptyDestFileField);
} }
self.transaction_params.dest_file_name[..dest_name.len_value()] self.transaction_params.file_properties.dest_file_name[..dest_name.len_value()]
.copy_from_slice(dest_name.value().unwrap()); .copy_from_slice(dest_name.value().unwrap());
self.transaction_params.dest_file_name_len = dest_name.len_value(); self.transaction_params.file_properties.dest_file_name_len = dest_name.len_value();
self.transaction_params.pdu_conf = *metadata_pdu.pdu_header().common_pdu_conf();
Ok(()) Ok(())
} }
@ -243,7 +263,7 @@ impl DestinationHandler {
let fd_pdu = FileDataPdu::from_bytes(raw_packet)?; let fd_pdu = FileDataPdu::from_bytes(raw_packet)?;
let mut dest_file = File::options() let mut dest_file = File::options()
.write(true) .write(true)
.open(&self.transaction_params.dest_path_buf)?; .open(&self.transaction_params.file_properties.dest_path_buf)?;
dest_file.seek(SeekFrom::Start(fd_pdu.offset()))?; dest_file.seek(SeekFrom::Start(fd_pdu.offset()))?;
dest_file.write_all(fd_pdu.file_data())?; dest_file.write_all(fd_pdu.file_data())?;
Ok(()) Ok(())
@ -279,7 +299,7 @@ impl DestinationHandler {
fn checksum_check(&mut self, expected_checksum: u32) -> Result<bool, DestError> { fn checksum_check(&mut self, expected_checksum: u32) -> Result<bool, DestError> {
let mut digest = CRC_32.digest(); let mut digest = CRC_32.digest();
let file_to_check = File::open(&self.transaction_params.dest_path_buf)?; let file_to_check = File::open(&self.transaction_params.file_properties.dest_path_buf)?;
let mut buf_reader = BufReader::new(file_to_check); let mut buf_reader = BufReader::new(file_to_check);
loop { loop {
let bytes_read = buf_reader.read(&mut self.transaction_params.cksum_buf)?; let bytes_read = buf_reader.read(&mut self.transaction_params.cksum_buf)?;
@ -327,11 +347,32 @@ impl DestinationHandler {
} }
fn transaction_start(&mut self) -> Result<(), DestError> { fn transaction_start(&mut self) -> Result<(), DestError> {
let dest_path = Path::new(from_utf8( let dest_name = from_utf8(
&self.transaction_params.dest_file_name[..self.transaction_params.dest_file_name_len], &self.transaction_params.file_properties.dest_file_name
)?); [..self.transaction_params.file_properties.dest_file_name_len],
)?;
self.transaction_params.dest_path_buf = dest_path.to_path_buf(); let dest_path = Path::new(dest_name);
self.transaction_params.file_properties.dest_path_buf = dest_path.to_path_buf();
let source_id = self.transaction_params.pdu_conf.source_id();
let id = TransactionId::new(
source_id,
self.transaction_params.pdu_conf.transaction_seq_num,
);
let src_name = from_utf8(
&self.transaction_params.file_properties.src_file_name
[0..self.transaction_params.file_properties.src_file_name_len],
)?;
let metadata_recvd_params = MetadataReceivedParams {
id,
source_id,
file_size: self.transaction_params.metadata_params.file_size,
src_file_name: src_name,
dest_file_name: dest_name,
msgs_to_user: &[],
};
self.transaction_params.transaction_id = Some(id);
self.cfdp_user
.metadata_recvd_indication(&metadata_recvd_params);
let metadata = metadata(dest_path)?; let metadata = metadata(dest_path)?;
if metadata.is_dir() { if metadata.is_dir() {
@ -340,7 +381,8 @@ impl DestinationHandler {
// and a destination name of /home/test, the resulting file name should be // and a destination name of /home/test, the resulting file name should be
// /home/test/hello.txt // /home/test/hello.txt
let source_path = Path::new(from_utf8( let source_path = Path::new(from_utf8(
&self.transaction_params.src_file_name[..self.transaction_params.src_file_name_len], &self.transaction_params.file_properties.src_file_name
[..self.transaction_params.file_properties.src_file_name_len],
)?); )?);
let source_name = source_path.file_name(); let source_name = source_path.file_name();
@ -348,15 +390,19 @@ impl DestinationHandler {
return Err(DestError::PathConcatError); return Err(DestError::PathConcatError);
} }
let source_name = source_name.unwrap(); let source_name = source_name.unwrap();
self.transaction_params.dest_path_buf.push(source_name); self.transaction_params
.file_properties
.dest_path_buf
.push(source_name);
} }
// This function does exactly what we require: Create a new file if it does not exist yet // This function does exactly what we require: Create a new file if it does not exist yet
// and trucate an existing one. // and trucate an existing one.
File::create(&self.transaction_params.dest_path_buf)?; File::create(&self.transaction_params.file_properties.dest_path_buf)?;
Ok(()) Ok(())
} }
fn transfer_completion(&mut self) -> Result<(), DestError> { fn transfer_completion(&mut self) -> Result<(), DestError> {
// This function should never be called with metadata parameters not set
if self.transaction_params.metadata_params.closure_requested { if self.transaction_params.metadata_params.closure_requested {
self.prepare_finished_pdu()?; self.prepare_finished_pdu()?;
} }
@ -444,7 +490,7 @@ mod tests {
fn test_basic() { fn test_basic() {
let test_id = UnsignedByteFieldU8::new(1); let test_id = UnsignedByteFieldU8::new(1);
let test_user = TestCfdpUser {}; let test_user = TestCfdpUser {};
let dest_handler = DestinationHandler::new(test_id, test_user); let dest_handler = DestinationHandler::new(test_id, Box::new(test_user));
assert_eq!(dest_handler.state(), State::Idle); assert_eq!(dest_handler.state(), State::Idle);
assert_eq!(dest_handler.step(), TransactionStep::Idle); assert_eq!(dest_handler.step(), TransactionStep::Idle);
} }