Skip to content

Commit

Permalink
continue with CFDP source handler
Browse files Browse the repository at this point in the history
  • Loading branch information
robamu committed Jul 15, 2024
1 parent ab56f4b commit 0aa3030
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 195 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ exclude = [
"embedded-examples/stm32f3-disco-rtic",
"embedded-examples/stm32h7-rtic",
]

2 changes: 1 addition & 1 deletion satrs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ default-features = false
version = "0.12"
default-features = false
git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
branch = "all-cfdp-updates"
branch = "main"

[dependencies.cobs]
git = "https://github.com/robamu/cobs.rs.git"
Expand Down
191 changes: 69 additions & 122 deletions satrs/src/cfdp/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ pub trait ReadablePutRequest {
fn trans_mode(&self) -> Option<TransmissionMode>;
fn closure_requested(&self) -> Option<bool>;
fn seg_ctrl(&self) -> Option<SegmentationControl>;
fn has_msgs_to_user(&self) -> bool;
fn msgs_to_user(&self, f: impl FnMut(&Tlv));
fn has_fault_handler_overrides(&self) -> bool;
fn fault_handler_overrides(&self, f: impl FnMut(&Tlv));

fn msgs_to_user(&self) -> Option<impl Iterator<Item = Tlv>>;
fn fault_handler_overrides(&self) -> Option<impl Iterator<Item = Tlv>>;
fn flow_label(&self) -> Option<Tlv>;
fn has_fs_requests(&self) -> bool;
fn fs_requests(&self, f: impl FnMut(&Tlv));
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>>;
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -101,44 +99,29 @@ impl ReadablePutRequest for PutRequest<'_, '_, '_, '_, '_, '_> {
self.seg_ctrl
}

fn has_msgs_to_user(&self) -> bool {
self.msgs_to_user.is_some() && self.msgs_to_user.unwrap().is_empty()
}

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 {
for msg_to_user in msgs_to_user {
f(msg_to_user)
}
return Some(msgs_to_user.iter().copied());
}
None
}

fn has_fault_handler_overrides(&self) -> bool {
self.fault_handler_overrides.is_some() && self.fault_handler_overrides.unwrap().is_empty()
}

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 {
for fh_override in fh_overrides {
f(fh_override)
}
return Some(fh_overrides.iter().copied());
}
None
}

fn flow_label(&self) -> Option<Tlv> {
self.flow_label
}

fn has_fs_requests(&self) -> bool {
self.fs_requests.is_some() && self.fs_requests.unwrap().is_empty()
}

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)
}
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>> {
if let Some(fs_requests) = self.msgs_to_user {
return Some(fs_requests.iter().copied());
}
None
}
}

Expand Down Expand Up @@ -382,45 +365,29 @@ pub mod alloc_mod {
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 {
for msg_to_user in msgs_to_user {
f(&msg_to_user.as_tlv())
}
return Some(msgs_to_user.iter().map(|tlv_owned| tlv_owned.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 {
for fh_override in fh_overrides {
f(&fh_override.as_tlv())
}
return Some(fh_overrides.iter().map(|tlv_owned| tlv_owned.as_tlv()));
}
None
}

fn flow_label(&self) -> Option<Tlv> {
self.flow_label.as_ref().map(|tlv| tlv.as_tlv())
}

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.as_tlv())
}
fn fs_requests(&self) -> Option<impl Iterator<Item = Tlv>> {
if let Some(requests) = &self.fs_requests {
return Some(requests.iter().map(|tlv_owned| tlv_owned.as_tlv()));
}
}

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()
None
}
}

Expand Down Expand Up @@ -470,18 +437,16 @@ pub mod alloc_mod {
/// to store TLVs or list of TLVs.
pub struct StaticPutRequestCacher {
pub static_fields: StaticPutRequestFields,
/// Static buffer to store file store requests.
pub fs_requests: alloc::vec::Vec<u8>,
/// Current total length of stored filestore requests.
pub fs_requests_len: usize,
opts_buf: alloc::vec::Vec<u8>,
opts_len: usize, // fs_request_start_end_pos: Option<(usize, usize)>
}

impl StaticPutRequestCacher {
pub fn new(max_fs_requests_storage: usize) -> Self {
pub fn new(max_len_opts_buf: usize) -> Self {
Self {
static_fields: StaticPutRequestFields::default(),
fs_requests: alloc::vec![0; max_fs_requests_storage],
fs_requests_len: 0,
opts_buf: alloc::vec![0; max_len_opts_buf],
opts_len: 0,
}
}

Expand Down Expand Up @@ -516,27 +481,30 @@ pub mod alloc_mod {
self.static_fields.closure_requested = put_request.closure_requested();
self.static_fields.seg_ctrl = put_request.seg_ctrl();
let mut current_idx = 0;
let mut error_if_too_large = None;
let mut store_fs_requests = |tlv: &Tlv| {
if current_idx + tlv.len_full() > self.fs_requests.len() {
error_if_too_large = Some(ByteConversionError::ToSliceTooSmall {
found: self.fs_requests.len(),
let mut store_tlv = |tlv: &Tlv| {
if current_idx + tlv.len_full() > self.opts_buf.len() {
return Err(ByteConversionError::ToSliceTooSmall {
found: self.opts_buf.len(),
expected: current_idx + tlv.len_full(),
});
return;
}
// We checked the buffer lengths, so this should never fail.
tlv.write_to_bytes(
&mut self.fs_requests[current_idx..current_idx + tlv.len_full()],
)
.unwrap();
tlv.write_to_bytes(&mut self.opts_buf[current_idx..current_idx + tlv.len_full()])
.unwrap();
current_idx += tlv.len_full();
Ok(())
};
put_request.fs_requests(&mut store_fs_requests);
if let Some(err) = error_if_too_large {
return Err(err);
if let Some(fs_req) = put_request.fs_requests() {
for fs_req in fs_req {
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(())
}

Expand All @@ -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
/// 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.
pub fn clear(&mut self) {
self.static_fields.clear();
self.fs_requests_len = 0;
self.opts_len = 0;
}
}
}
Expand All @@ -592,15 +568,9 @@ mod tests {
assert_eq!(put_request.seg_ctrl(), None);
assert_eq!(put_request.closure_requested(), None);
assert_eq!(put_request.trans_mode(), None);
assert!(!put_request.has_fs_requests());
let dummy = |_tlv: &Tlv| {
panic!("should not be called");
};
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.fs_requests().is_none());
assert!(put_request.msgs_to_user().is_none());
assert!(put_request.fault_handler_overrides().is_none());
assert!(put_request.flow_label().is_none());
}

Expand All @@ -617,44 +587,27 @@ mod tests {
assert_eq!(put_request.seg_ctrl(), None);
assert_eq!(put_request.closure_requested(), None);
assert_eq!(put_request.trans_mode(), None);
assert!(!put_request.has_fs_requests());
let dummy = |_tlv: &Tlv| {
panic!("should not be called");
};
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.fs_requests().is_none());
assert!(put_request.msgs_to_user().is_none());
assert!(put_request.fault_handler_overrides().is_none());
assert!(put_request.flow_label().is_none());
let put_request_cloned = put_request.clone();
assert_eq!(put_request, put_request_cloned);
}

#[test]
fn test_put_request_cacher_basic() {
let cacher_cfg = PutRequestCacheConfig {
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);
let put_request_cached = StaticPutRequestCacher::new(128);
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.fs_requests_len, 0);
assert_eq!(put_request_cached.fs_requests.len(), 512);
assert_eq!(put_request_cached.opts_len(), 0);
assert_eq!(put_request_cached.opts_slice(), &[]);
}

#[test]
fn test_put_request_cacher_set() {
let cacher_cfg = PutRequestCacheConfig {
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 mut put_request_cached = StaticPutRequestCacher::new(128);
let src_file = "/tmp/hello.txt";
let dest_file = "/tmp/hello2.txt";
let put_request =
Expand All @@ -671,18 +624,12 @@ mod tests {
);
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.fs_requests_len, 0);
assert_eq!(put_request_cached.opts_len(), 0);
}

#[test]
fn test_put_request_cacher_set_and_clear() {
let cacher_cfg = PutRequestCacheConfig {
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 mut put_request_cached = StaticPutRequestCacher::new(128);
let src_file = "/tmp/hello.txt";
let dest_file = "/tmp/hello2.txt";
let put_request =
Expand All @@ -692,6 +639,6 @@ mod tests {
put_request_cached.clear();
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.fs_requests_len, 0);
assert_eq!(put_request_cached.opts_len(), 0);
}
}
Loading

0 comments on commit 0aa3030

Please sign in to comment.