CFDP extracted to library #201
@ -12,4 +12,3 @@ exclude = [
|
|||||||
"embedded-examples/stm32f3-disco-rtic",
|
"embedded-examples/stm32f3-disco-rtic",
|
||||||
"embedded-examples/stm32h7-rtic",
|
"embedded-examples/stm32h7-rtic",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ default-features = false
|
|||||||
version = "0.12"
|
version = "0.12"
|
||||||
default-features = false
|
default-features = false
|
||||||
git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
|
git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
|
||||||
branch = "all-cfdp-updates"
|
branch = "main"
|
||||||
|
|
||||||
[dependencies.cobs]
|
[dependencies.cobs]
|
||||||
git = "https://github.com/robamu/cobs.rs.git"
|
git = "https://github.com/robamu/cobs.rs.git"
|
||||||
|
@ -21,13 +21,11 @@ pub trait ReadablePutRequest {
|
|||||||
fn trans_mode(&self) -> Option<TransmissionMode>;
|
fn trans_mode(&self) -> Option<TransmissionMode>;
|
||||||
fn closure_requested(&self) -> Option<bool>;
|
fn closure_requested(&self) -> Option<bool>;
|
||||||
fn seg_ctrl(&self) -> Option<SegmentationControl>;
|
fn seg_ctrl(&self) -> Option<SegmentationControl>;
|
||||||
fn has_msgs_to_user(&self) -> bool;
|
|
||||||
fn msgs_to_user(&self, f: impl FnMut(&Tlv));
|
fn msgs_to_user(&self) -> Option<impl Iterator<Item = Tlv>>;
|
||||||
fn has_fault_handler_overrides(&self) -> bool;
|
fn fault_handler_overrides(&self) -> Option<impl Iterator<Item = Tlv>>;
|
||||||
fn fault_handler_overrides(&self, f: impl FnMut(&Tlv));
|
|
||||||
fn flow_label(&self) -> Option<Tlv>;
|
fn flow_label(&self) -> Option<Tlv>;
|
||||||
fn has_fs_requests(&self) -> bool;
|
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>>;
|
||||||
fn fs_requests(&self, f: impl FnMut(&Tlv));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
@ -101,44 +99,29 @@ impl ReadablePutRequest for PutRequest<'_, '_, '_, '_, '_, '_> {
|
|||||||
self.seg_ctrl
|
self.seg_ctrl
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_msgs_to_user(&self) -> bool {
|
fn msgs_to_user(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
self.msgs_to_user.is_some() && self.msgs_to_user.unwrap().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn msgs_to_user(&self, mut f: impl FnMut(&Tlv)) {
|
|
||||||
if let Some(msgs_to_user) = self.msgs_to_user {
|
if let Some(msgs_to_user) = self.msgs_to_user {
|
||||||
for msg_to_user in msgs_to_user {
|
return Some(msgs_to_user.iter().copied());
|
||||||
f(msg_to_user)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_fault_handler_overrides(&self) -> bool {
|
fn fault_handler_overrides(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
self.fault_handler_overrides.is_some() && self.fault_handler_overrides.unwrap().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fault_handler_overrides(&self, mut f: impl FnMut(&Tlv)) {
|
|
||||||
if let Some(fh_overrides) = self.fault_handler_overrides {
|
if let Some(fh_overrides) = self.fault_handler_overrides {
|
||||||
for fh_override in fh_overrides {
|
return Some(fh_overrides.iter().copied());
|
||||||
f(fh_override)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flow_label(&self) -> Option<Tlv> {
|
fn flow_label(&self) -> Option<Tlv> {
|
||||||
self.flow_label
|
self.flow_label
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_fs_requests(&self) -> bool {
|
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
self.fs_requests.is_some() && self.fs_requests.unwrap().is_empty()
|
if let Some(fs_requests) = self.msgs_to_user {
|
||||||
}
|
return Some(fs_requests.iter().copied());
|
||||||
|
|
||||||
fn fs_requests(&self, mut f: impl FnMut(&Tlv)) {
|
|
||||||
if let Some(fs_requests) = self.fs_requests {
|
|
||||||
for fs_request in fs_requests {
|
|
||||||
f(fs_request)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,45 +365,29 @@ pub mod alloc_mod {
|
|||||||
self.seg_ctrl
|
self.seg_ctrl
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msgs_to_user(&self, mut f: impl FnMut(&Tlv)) {
|
fn msgs_to_user(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
if let Some(msgs_to_user) = &self.msgs_to_user {
|
if let Some(msgs_to_user) = &self.msgs_to_user {
|
||||||
for msg_to_user in msgs_to_user {
|
return Some(msgs_to_user.iter().map(|tlv_owned| tlv_owned.as_tlv()));
|
||||||
f(&msg_to_user.as_tlv())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fault_handler_overrides(&self, mut f: impl FnMut(&Tlv)) {
|
fn fault_handler_overrides(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
if let Some(fh_overrides) = &self.fault_handler_overrides {
|
if let Some(fh_overrides) = &self.fault_handler_overrides {
|
||||||
for fh_override in fh_overrides {
|
return Some(fh_overrides.iter().map(|tlv_owned| tlv_owned.as_tlv()));
|
||||||
f(&fh_override.as_tlv())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flow_label(&self) -> Option<Tlv> {
|
fn flow_label(&self) -> Option<Tlv> {
|
||||||
self.flow_label.as_ref().map(|tlv| tlv.as_tlv())
|
self.flow_label.as_ref().map(|tlv| tlv.as_tlv())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fs_requests(&self, mut f: impl FnMut(&Tlv)) {
|
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>> {
|
||||||
if let Some(fs_requests) = &self.fs_requests {
|
if let Some(requests) = &self.fs_requests {
|
||||||
for fs_request in fs_requests {
|
return Some(requests.iter().map(|tlv_owned| tlv_owned.as_tlv()));
|
||||||
f(&fs_request.as_tlv())
|
|
||||||
}
|
}
|
||||||
}
|
None
|
||||||
}
|
|
||||||
|
|
||||||
fn has_msgs_to_user(&self) -> bool {
|
|
||||||
self.msgs_to_user.is_some() && !self.msgs_to_user.as_ref().unwrap().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_fault_handler_overrides(&self) -> bool {
|
|
||||||
self.fault_handler_overrides.is_some()
|
|
||||||
&& !self.fault_handler_overrides.as_ref().unwrap().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_fs_requests(&self) -> bool {
|
|
||||||
self.fs_requests.is_some() && !self.fs_requests.as_ref().unwrap().is_empty()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,18 +437,16 @@ pub mod alloc_mod {
|
|||||||
/// to store TLVs or list of TLVs.
|
/// to store TLVs or list of TLVs.
|
||||||
pub struct StaticPutRequestCacher {
|
pub struct StaticPutRequestCacher {
|
||||||
pub static_fields: StaticPutRequestFields,
|
pub static_fields: StaticPutRequestFields,
|
||||||
/// Static buffer to store file store requests.
|
opts_buf: alloc::vec::Vec<u8>,
|
||||||
pub fs_requests: alloc::vec::Vec<u8>,
|
opts_len: usize, // fs_request_start_end_pos: Option<(usize, usize)>
|
||||||
/// Current total length of stored filestore requests.
|
|
||||||
pub fs_requests_len: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StaticPutRequestCacher {
|
impl StaticPutRequestCacher {
|
||||||
pub fn new(max_fs_requests_storage: usize) -> Self {
|
pub fn new(max_len_opts_buf: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
static_fields: StaticPutRequestFields::default(),
|
static_fields: StaticPutRequestFields::default(),
|
||||||
fs_requests: alloc::vec![0; max_fs_requests_storage],
|
opts_buf: alloc::vec![0; max_len_opts_buf],
|
||||||
fs_requests_len: 0,
|
opts_len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,27 +481,30 @@ pub mod alloc_mod {
|
|||||||
self.static_fields.closure_requested = put_request.closure_requested();
|
self.static_fields.closure_requested = put_request.closure_requested();
|
||||||
self.static_fields.seg_ctrl = put_request.seg_ctrl();
|
self.static_fields.seg_ctrl = put_request.seg_ctrl();
|
||||||
let mut current_idx = 0;
|
let mut current_idx = 0;
|
||||||
let mut error_if_too_large = None;
|
let mut store_tlv = |tlv: &Tlv| {
|
||||||
let mut store_fs_requests = |tlv: &Tlv| {
|
if current_idx + tlv.len_full() > self.opts_buf.len() {
|
||||||
if current_idx + tlv.len_full() > self.fs_requests.len() {
|
return Err(ByteConversionError::ToSliceTooSmall {
|
||||||
error_if_too_large = Some(ByteConversionError::ToSliceTooSmall {
|
found: self.opts_buf.len(),
|
||||||
found: self.fs_requests.len(),
|
|
||||||
expected: current_idx + tlv.len_full(),
|
expected: current_idx + tlv.len_full(),
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// We checked the buffer lengths, so this should never fail.
|
// We checked the buffer lengths, so this should never fail.
|
||||||
tlv.write_to_bytes(
|
tlv.write_to_bytes(&mut self.opts_buf[current_idx..current_idx + tlv.len_full()])
|
||||||
&mut self.fs_requests[current_idx..current_idx + tlv.len_full()],
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
current_idx += tlv.len_full();
|
current_idx += tlv.len_full();
|
||||||
|
Ok(())
|
||||||
};
|
};
|
||||||
put_request.fs_requests(&mut store_fs_requests);
|
if let Some(fs_req) = put_request.fs_requests() {
|
||||||
if let Some(err) = error_if_too_large {
|
for fs_req in fs_req {
|
||||||
return Err(err);
|
store_tlv(&fs_req)?;
|
||||||
}
|
}
|
||||||
self.fs_requests_len = current_idx;
|
}
|
||||||
|
if let Some(msgs_to_user) = put_request.msgs_to_user() {
|
||||||
|
for msg_to_user in msgs_to_user {
|
||||||
|
store_tlv(&msg_to_user)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.opts_len = current_idx;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,13 +528,21 @@ pub mod alloc_mod {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn opts_len(&self) -> usize {
|
||||||
|
self.opts_len
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opts_slice(&self) -> &[u8] {
|
||||||
|
&self.opts_buf[0..self.opts_len]
|
||||||
|
}
|
||||||
|
|
||||||
/// This clears the cacher structure. This is a cheap operation because it only
|
/// This clears the cacher structure. This is a cheap operation because it only
|
||||||
/// sets [Option]al values to [None] and the length of stores TLVs to 0.
|
/// sets [Option]al values to [None] and the length of stores TLVs to 0.
|
||||||
///
|
///
|
||||||
/// Please note that this method will not set the values in the buffer to 0.
|
/// Please note that this method will not set the values in the buffer to 0.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.static_fields.clear();
|
self.static_fields.clear();
|
||||||
self.fs_requests_len = 0;
|
self.opts_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -592,15 +568,9 @@ mod tests {
|
|||||||
assert_eq!(put_request.seg_ctrl(), None);
|
assert_eq!(put_request.seg_ctrl(), None);
|
||||||
assert_eq!(put_request.closure_requested(), None);
|
assert_eq!(put_request.closure_requested(), None);
|
||||||
assert_eq!(put_request.trans_mode(), None);
|
assert_eq!(put_request.trans_mode(), None);
|
||||||
assert!(!put_request.has_fs_requests());
|
assert!(put_request.fs_requests().is_none());
|
||||||
let dummy = |_tlv: &Tlv| {
|
assert!(put_request.msgs_to_user().is_none());
|
||||||
panic!("should not be called");
|
assert!(put_request.fault_handler_overrides().is_none());
|
||||||
};
|
|
||||||
put_request.fs_requests(&dummy);
|
|
||||||
assert!(!put_request.has_msgs_to_user());
|
|
||||||
put_request.msgs_to_user(&dummy);
|
|
||||||
assert!(!put_request.has_fault_handler_overrides());
|
|
||||||
put_request.fault_handler_overrides(&dummy);
|
|
||||||
assert!(put_request.flow_label().is_none());
|
assert!(put_request.flow_label().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,15 +587,10 @@ mod tests {
|
|||||||
assert_eq!(put_request.seg_ctrl(), None);
|
assert_eq!(put_request.seg_ctrl(), None);
|
||||||
assert_eq!(put_request.closure_requested(), None);
|
assert_eq!(put_request.closure_requested(), None);
|
||||||
assert_eq!(put_request.trans_mode(), None);
|
assert_eq!(put_request.trans_mode(), None);
|
||||||
assert!(!put_request.has_fs_requests());
|
assert!(put_request.flow_label().is_none());
|
||||||
let dummy = |_tlv: &Tlv| {
|
assert!(put_request.fs_requests().is_none());
|
||||||
panic!("should not be called");
|
assert!(put_request.msgs_to_user().is_none());
|
||||||
};
|
assert!(put_request.fault_handler_overrides().is_none());
|
||||||
put_request.fs_requests(&dummy);
|
|
||||||
assert!(!put_request.has_msgs_to_user());
|
|
||||||
put_request.msgs_to_user(&dummy);
|
|
||||||
assert!(!put_request.has_fault_handler_overrides());
|
|
||||||
put_request.fault_handler_overrides(&dummy);
|
|
||||||
assert!(put_request.flow_label().is_none());
|
assert!(put_request.flow_label().is_none());
|
||||||
let put_request_cloned = put_request.clone();
|
let put_request_cloned = put_request.clone();
|
||||||
assert_eq!(put_request, put_request_cloned);
|
assert_eq!(put_request, put_request_cloned);
|
||||||
@ -633,28 +598,16 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_cacher_basic() {
|
fn test_put_request_cacher_basic() {
|
||||||
let cacher_cfg = PutRequestCacheConfig {
|
let put_request_cached = StaticPutRequestCacher::new(128);
|
||||||
max_msgs_to_user_storage: 512,
|
|
||||||
max_fault_handler_overrides_storage: 128,
|
|
||||||
max_flow_label_storage: 128,
|
|
||||||
max_fs_requests_storage: 512,
|
|
||||||
};
|
|
||||||
let put_request_cached = StaticPutRequestCacher::new(cacher_cfg);
|
|
||||||
assert_eq!(put_request_cached.static_fields.source_file_len, 0);
|
assert_eq!(put_request_cached.static_fields.source_file_len, 0);
|
||||||
assert_eq!(put_request_cached.static_fields.dest_file_len, 0);
|
assert_eq!(put_request_cached.static_fields.dest_file_len, 0);
|
||||||
assert_eq!(put_request_cached.fs_requests_len, 0);
|
assert_eq!(put_request_cached.opts_len(), 0);
|
||||||
assert_eq!(put_request_cached.fs_requests.len(), 512);
|
assert_eq!(put_request_cached.opts_slice(), &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_cacher_set() {
|
fn test_put_request_cacher_set() {
|
||||||
let cacher_cfg = PutRequestCacheConfig {
|
let mut put_request_cached = StaticPutRequestCacher::new(128);
|
||||||
max_msgs_to_user_storage: 512,
|
|
||||||
max_fault_handler_overrides_storage: 128,
|
|
||||||
max_flow_label_storage: 128,
|
|
||||||
max_fs_requests_storage: 512,
|
|
||||||
};
|
|
||||||
let mut put_request_cached = StaticPutRequestCacher::new(cacher_cfg);
|
|
||||||
let src_file = "/tmp/hello.txt";
|
let src_file = "/tmp/hello.txt";
|
||||||
let dest_file = "/tmp/hello2.txt";
|
let dest_file = "/tmp/hello2.txt";
|
||||||
let put_request =
|
let put_request =
|
||||||
@ -671,18 +624,12 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(put_request_cached.source_file().unwrap(), src_file);
|
assert_eq!(put_request_cached.source_file().unwrap(), src_file);
|
||||||
assert_eq!(put_request_cached.dest_file().unwrap(), dest_file);
|
assert_eq!(put_request_cached.dest_file().unwrap(), dest_file);
|
||||||
assert_eq!(put_request_cached.fs_requests_len, 0);
|
assert_eq!(put_request_cached.opts_len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_cacher_set_and_clear() {
|
fn test_put_request_cacher_set_and_clear() {
|
||||||
let cacher_cfg = PutRequestCacheConfig {
|
let mut put_request_cached = StaticPutRequestCacher::new(128);
|
||||||
max_msgs_to_user_storage: 512,
|
|
||||||
max_fault_handler_overrides_storage: 128,
|
|
||||||
max_flow_label_storage: 128,
|
|
||||||
max_fs_requests_storage: 512,
|
|
||||||
};
|
|
||||||
let mut put_request_cached = StaticPutRequestCacher::new(cacher_cfg);
|
|
||||||
let src_file = "/tmp/hello.txt";
|
let src_file = "/tmp/hello.txt";
|
||||||
let dest_file = "/tmp/hello2.txt";
|
let dest_file = "/tmp/hello2.txt";
|
||||||
let put_request =
|
let put_request =
|
||||||
@ -692,6 +639,6 @@ mod tests {
|
|||||||
put_request_cached.clear();
|
put_request_cached.clear();
|
||||||
assert_eq!(put_request_cached.static_fields.source_file_len, 0);
|
assert_eq!(put_request_cached.static_fields.source_file_len, 0);
|
||||||
assert_eq!(put_request_cached.static_fields.dest_file_len, 0);
|
assert_eq!(put_request_cached.static_fields.dest_file_len, 0);
|
||||||
assert_eq!(put_request_cached.fs_requests_len, 0);
|
assert_eq!(put_request_cached.opts_len(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use core::str::Utf8Error;
|
use core::{cell::RefCell, str::Utf8Error};
|
||||||
|
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
cfdp::{
|
cfdp::{
|
||||||
lv::Lv,
|
lv::Lv,
|
||||||
pdu::{
|
pdu::{
|
||||||
metadata::{MetadataGenericParams, MetadataPduCreator},
|
metadata::{MetadataGenericParams, MetadataPduCreator},
|
||||||
CommonPduConfig, FileDirectiveType, PduHeader,
|
CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, WritablePduPacket,
|
||||||
},
|
},
|
||||||
Direction, LargeFileFlag, PduType,
|
Direction, LargeFileFlag, PduType,
|
||||||
},
|
},
|
||||||
@ -92,6 +92,8 @@ pub enum SourceError {
|
|||||||
SourceFileNotValidUtf8(Utf8Error),
|
SourceFileNotValidUtf8(Utf8Error),
|
||||||
#[error("destination file does not have valid UTF8 format: {0}")]
|
#[error("destination file does not have valid UTF8 format: {0}")]
|
||||||
DestFileNotValidUtf8(Utf8Error),
|
DestFileNotValidUtf8(Utf8Error),
|
||||||
|
#[error("error related to PDU creation")]
|
||||||
|
Pdu(#[from] PduError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
@ -111,6 +113,7 @@ pub struct SourceHandler<
|
|||||||
> {
|
> {
|
||||||
local_cfg: LocalEntityConfig<UserFaultHook>,
|
local_cfg: LocalEntityConfig<UserFaultHook>,
|
||||||
pdu_sender: PduSender,
|
pdu_sender: PduSender,
|
||||||
|
pdu_buffer: RefCell<alloc::vec::Vec<u8>>,
|
||||||
put_request_cacher: StaticPutRequestCacher,
|
put_request_cacher: StaticPutRequestCacher,
|
||||||
remote_cfg_table: RemoteCfgTable,
|
remote_cfg_table: RemoteCfgTable,
|
||||||
vfs: Vfs,
|
vfs: Vfs,
|
||||||
@ -137,6 +140,7 @@ impl<
|
|||||||
pdu_sender: PduSender,
|
pdu_sender: PduSender,
|
||||||
vfs: Vfs,
|
vfs: Vfs,
|
||||||
put_request_cacher: StaticPutRequestCacher,
|
put_request_cacher: StaticPutRequestCacher,
|
||||||
|
max_pdu_len: usize,
|
||||||
remote_cfg_table: RemoteCfgTable,
|
remote_cfg_table: RemoteCfgTable,
|
||||||
seq_count_provider: SeqCountProvider,
|
seq_count_provider: SeqCountProvider,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -144,6 +148,7 @@ impl<
|
|||||||
local_cfg: cfg,
|
local_cfg: cfg,
|
||||||
remote_cfg_table,
|
remote_cfg_table,
|
||||||
pdu_sender,
|
pdu_sender,
|
||||||
|
pdu_buffer: RefCell::new(alloc::vec![0; max_pdu_len]),
|
||||||
vfs,
|
vfs,
|
||||||
put_request_cacher,
|
put_request_cacher,
|
||||||
state_helper: Default::default(),
|
state_helper: Default::default(),
|
||||||
@ -283,7 +288,7 @@ impl<
|
|||||||
self.state_helper.step = TransactionStep::SendingMetadata;
|
self.state_helper.step = TransactionStep::SendingMetadata;
|
||||||
}
|
}
|
||||||
if self.state_helper.step == TransactionStep::SendingMetadata {
|
if self.state_helper.step == TransactionStep::SendingMetadata {
|
||||||
self.prepare_and_send_metadata_pdu();
|
self.prepare_and_send_metadata_pdu()?;
|
||||||
}
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
@ -346,52 +351,42 @@ impl<
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_and_send_metadata_pdu(&self) {
|
fn prepare_and_send_metadata_pdu(&self) -> Result<(), PduError> {
|
||||||
let tstate = &self.tstate.expect("transfer state unexpectedly empty");
|
let tstate = &self.tstate.expect("transfer state unexpectedly empty");
|
||||||
if self.fparams.metadata_only {
|
|
||||||
let metadata_params = MetadataGenericParams::new(
|
let metadata_params = MetadataGenericParams::new(
|
||||||
tstate.closure_requested,
|
tstate.closure_requested,
|
||||||
tstate.remote_cfg.default_crc_type,
|
tstate.remote_cfg.default_crc_type,
|
||||||
self.fparams.file_size,
|
self.fparams.file_size,
|
||||||
);
|
);
|
||||||
|
if self.fparams.metadata_only {
|
||||||
let metadata_pdu = MetadataPduCreator::new(
|
let metadata_pdu = MetadataPduCreator::new(
|
||||||
PduHeader::new_no_file_data(self.pdu_conf, 0),
|
PduHeader::new_no_file_data(self.pdu_conf, 0),
|
||||||
metadata_params,
|
metadata_params,
|
||||||
Lv::new_empty(),
|
Lv::new_empty(),
|
||||||
Lv::new_empty(),
|
Lv::new_empty(),
|
||||||
&[],
|
self.put_request_cacher.opts_slice(),
|
||||||
);
|
);
|
||||||
//self.pdu_sender.send_pdu(pdu_type, file_directive_type, raw_pdu)
|
return self.pdu_send_helper(metadata_pdu);
|
||||||
}
|
}
|
||||||
/*
|
let metadata_pdu = MetadataPduCreator::new(
|
||||||
assert self._put_req is not None
|
PduHeader::new_no_file_data(self.pdu_conf, 0),
|
||||||
options = []
|
metadata_params,
|
||||||
if self._put_req.metadata_only:
|
Lv::new_from_str(self.put_request_cacher.source_file().unwrap()).unwrap(),
|
||||||
params = MetadataParams(
|
Lv::new_from_str(self.put_request_cacher.dest_file().unwrap()).unwrap(),
|
||||||
closure_requested=self._params.closure_requested,
|
self.put_request_cacher.opts_slice(),
|
||||||
checksum_type=self._crc_helper.checksum_type,
|
);
|
||||||
file_size=0,
|
self.pdu_send_helper(metadata_pdu)
|
||||||
dest_file_name=None,
|
}
|
||||||
source_file_name=None,
|
|
||||||
)
|
fn pdu_send_helper(&self, pdu: impl WritablePduPacket + CfdpPdu) -> Result<(), PduError> {
|
||||||
else:
|
let mut pdu_buffer_mut = self.pdu_buffer.borrow_mut();
|
||||||
# Funny name.
|
let written_len = pdu.write_to_bytes(&mut pdu_buffer_mut)?;
|
||||||
params = self._prepare_metadata_base_params_with_metadata()
|
self.pdu_sender.send_pdu(
|
||||||
if self._put_req.fs_requests is not None:
|
PduType::FileDirective,
|
||||||
for fs_request in self._put_req.fs_requests:
|
Some(FileDirectiveType::MetadataPdu),
|
||||||
options.append(fs_request)
|
&pdu_buffer_mut[0..written_len],
|
||||||
if self._put_req.fault_handler_overrides is not None:
|
)?;
|
||||||
for fh_override in self._put_req.fault_handler_overrides:
|
Ok(())
|
||||||
options.append(fh_override)
|
|
||||||
if self._put_req.flow_label_tlv is not None:
|
|
||||||
options.append(self._put_req.flow_label_tlv)
|
|
||||||
if self._put_req.msgs_to_user is not None:
|
|
||||||
for msg_to_user in self._put_req.msgs_to_user:
|
|
||||||
options.append(msg_to_user)
|
|
||||||
self._add_packet_to_be_sent(
|
|
||||||
MetadataPdu(pdu_conf=self._params.pdu_conf, params=params, options=options)
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_finished_pdu(&mut self) {}
|
fn handle_finished_pdu(&mut self) {}
|
||||||
@ -441,6 +436,7 @@ mod tests {
|
|||||||
test_packet_sender,
|
test_packet_sender,
|
||||||
NativeFilestore::default(),
|
NativeFilestore::default(),
|
||||||
static_put_request_cacher,
|
static_put_request_cacher,
|
||||||
|
1024,
|
||||||
basic_remote_cfg_table(),
|
basic_remote_cfg_table(),
|
||||||
SeqCountProviderSimple::default(),
|
SeqCountProviderSimple::default(),
|
||||||
)
|
)
|
||||||
|
@ -1584,23 +1584,21 @@ mod tests {
|
|||||||
mod heapless_tests {
|
mod heapless_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::static_subpool;
|
use crate::static_subpool;
|
||||||
use core::mem::MaybeUninit;
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
const SUBPOOL_1_BLOCK_SIZE: usize = 4;
|
const SUBPOOL_1_BLOCK_SIZE: usize = 4;
|
||||||
const SUBPOOL_1_NUM_ELEMENTS: u16 = 4;
|
const SUBPOOL_1_NUM_ELEMENTS: u16 = 4;
|
||||||
static mut SUBPOOL_1: MaybeUninit<
|
static mut SUBPOOL_1: [u8; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE] =
|
||||||
[u8; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE],
|
[0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE];
|
||||||
> = MaybeUninit::new([0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE]);
|
static mut SUBPOOL_1_SIZES: [usize; SUBPOOL_1_NUM_ELEMENTS as usize] =
|
||||||
static mut SUBPOOL_1_SIZES: MaybeUninit<[usize; SUBPOOL_1_NUM_ELEMENTS as usize]> =
|
[STORE_FREE; SUBPOOL_1_NUM_ELEMENTS as usize];
|
||||||
MaybeUninit::new([STORE_FREE; SUBPOOL_1_NUM_ELEMENTS as usize]);
|
|
||||||
|
|
||||||
const SUBPOOL_2_NUM_ELEMENTS: u16 = 2;
|
const SUBPOOL_2_NUM_ELEMENTS: u16 = 2;
|
||||||
const SUBPOOL_2_BLOCK_SIZE: usize = 8;
|
const SUBPOOL_2_BLOCK_SIZE: usize = 8;
|
||||||
static mut SUBPOOL_2: MaybeUninit<
|
static mut SUBPOOL_2: [u8; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE] =
|
||||||
[u8; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE],
|
[0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE];
|
||||||
> = MaybeUninit::new([0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE]);
|
static mut SUBPOOL_2_SIZES: [usize; SUBPOOL_2_NUM_ELEMENTS as usize] =
|
||||||
static mut SUBPOOL_2_SIZES: MaybeUninit<[usize; SUBPOOL_2_NUM_ELEMENTS as usize]> =
|
[STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize];
|
||||||
MaybeUninit::new([STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize]);
|
|
||||||
|
|
||||||
const SUBPOOL_3_NUM_ELEMENTS: u16 = 1;
|
const SUBPOOL_3_NUM_ELEMENTS: u16 = 1;
|
||||||
const SUBPOOL_3_BLOCK_SIZE: usize = 16;
|
const SUBPOOL_3_BLOCK_SIZE: usize = 16;
|
||||||
@ -1643,18 +1641,18 @@ mod tests {
|
|||||||
StaticHeaplessMemoryPool::new(false);
|
StaticHeaplessMemoryPool::new(false);
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
.grow(
|
.grow(
|
||||||
unsafe { SUBPOOL_1.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_1) },
|
||||||
unsafe { SUBPOOL_1_SIZES.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_1_SIZES) },
|
||||||
SUBPOOL_1_NUM_ELEMENTS,
|
SUBPOOL_1_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
.grow(
|
.grow(
|
||||||
unsafe { SUBPOOL_2.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_2) },
|
||||||
unsafe { SUBPOOL_2_SIZES.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_2_SIZES) },
|
||||||
SUBPOOL_2_NUM_ELEMENTS,
|
SUBPOOL_2_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1662,7 +1660,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_3.assume_init_mut() },
|
unsafe { SUBPOOL_3.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_3_NUM_ELEMENTS,
|
SUBPOOL_3_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
heapless_pool
|
heapless_pool
|
||||||
@ -1782,10 +1780,10 @@ mod tests {
|
|||||||
StaticHeaplessMemoryPool::new(true);
|
StaticHeaplessMemoryPool::new(true);
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
.grow(
|
.grow(
|
||||||
unsafe { SUBPOOL_2.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_2) },
|
||||||
unsafe { SUBPOOL_2_SIZES.assume_init_mut() },
|
unsafe { &mut *addr_of_mut!(SUBPOOL_2_SIZES) },
|
||||||
SUBPOOL_2_NUM_ELEMENTS,
|
SUBPOOL_2_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1793,7 +1791,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_4.assume_init_mut() },
|
unsafe { SUBPOOL_4.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_4_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_4_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_4_NUM_ELEMENTS,
|
SUBPOOL_4_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
generic_test_spills_to_higher_subpools(&mut heapless_pool);
|
generic_test_spills_to_higher_subpools(&mut heapless_pool);
|
||||||
@ -1808,7 +1806,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_5.assume_init_mut() },
|
unsafe { SUBPOOL_5.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_5_NUM_ELEMENTS,
|
SUBPOOL_5_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1816,7 +1814,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_3.assume_init_mut() },
|
unsafe { SUBPOOL_3.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_3_NUM_ELEMENTS,
|
SUBPOOL_3_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
generic_test_spillage_fails_as_well(&mut heapless_pool);
|
generic_test_spillage_fails_as_well(&mut heapless_pool);
|
||||||
@ -1831,7 +1829,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_5.assume_init_mut() },
|
unsafe { SUBPOOL_5.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_5_NUM_ELEMENTS,
|
SUBPOOL_5_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1839,7 +1837,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_6.assume_init_mut() },
|
unsafe { SUBPOOL_6.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_6_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_6_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_6_NUM_ELEMENTS,
|
SUBPOOL_6_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1847,7 +1845,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_3.assume_init_mut() },
|
unsafe { SUBPOOL_3.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_3_NUM_ELEMENTS,
|
SUBPOOL_3_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
generic_test_spillage_works_across_multiple_subpools(&mut heapless_pool);
|
generic_test_spillage_works_across_multiple_subpools(&mut heapless_pool);
|
||||||
@ -1862,7 +1860,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_5.assume_init_mut() },
|
unsafe { SUBPOOL_5.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_5_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_5_NUM_ELEMENTS,
|
SUBPOOL_5_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1870,7 +1868,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_6.assume_init_mut() },
|
unsafe { SUBPOOL_6.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_6_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_6_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_6_NUM_ELEMENTS,
|
SUBPOOL_6_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(heapless_pool
|
assert!(heapless_pool
|
||||||
@ -1878,7 +1876,7 @@ mod tests {
|
|||||||
unsafe { SUBPOOL_3.assume_init_mut() },
|
unsafe { SUBPOOL_3.assume_init_mut() },
|
||||||
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
unsafe { SUBPOOL_3_SIZES.assume_init_mut() },
|
||||||
SUBPOOL_3_NUM_ELEMENTS,
|
SUBPOOL_3_NUM_ELEMENTS,
|
||||||
false
|
true
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
generic_test_spillage_fails_across_multiple_subpools(&mut heapless_pool);
|
generic_test_spillage_fails_across_multiple_subpools(&mut heapless_pool);
|
||||||
|
@ -1702,7 +1702,7 @@ pub mod tests {
|
|||||||
};
|
};
|
||||||
use crate::pus::{ChannelWithId, PusTmVariant};
|
use crate::pus::{ChannelWithId, PusTmVariant};
|
||||||
use crate::request::MessageMetadata;
|
use crate::request::MessageMetadata;
|
||||||
use crate::seq_count::{CcsdsSimpleSeqCountProvider, SequenceCountProviderCore};
|
use crate::seq_count::{CcsdsSimpleSeqCountProvider, SequenceCountProvider};
|
||||||
use crate::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
|
use crate::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
|
||||||
use crate::ComponentId;
|
use crate::ComponentId;
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
Loading…
Reference in New Issue
Block a user