CFDP extracted to library #201
@ -679,7 +679,7 @@ impl<
|
||||
// TODO: This is the only remaining function which uses std.. the easiest way would
|
||||
// probably be to use a static pre-allocated dest path buffer to store any concatenated
|
||||
// paths.
|
||||
if dest_path.exists() && self.vfs.is_dir(dest_path.to_str().unwrap()) {
|
||||
if dest_path.exists() && self.vfs.is_dir(dest_path.to_str().unwrap())? {
|
||||
// Create new destination path by concatenating the last part of the source source
|
||||
// name and the destination folder. For example, for a source file of /tmp/hello.txt
|
||||
// and a destination name of /home/test, the resulting file name should be
|
||||
@ -696,7 +696,7 @@ impl<
|
||||
self.tparams.file_properties.dest_path_buf.push(source_name);
|
||||
}
|
||||
let dest_path_str = self.tparams.file_properties.dest_path_buf.to_str().unwrap();
|
||||
if self.vfs.exists(dest_path_str) {
|
||||
if self.vfs.exists(dest_path_str)? {
|
||||
self.vfs.truncate_file(dest_path_str)?;
|
||||
} else {
|
||||
self.vfs.create_file(dest_path_str)?;
|
||||
|
@ -123,13 +123,15 @@ pub trait VirtualFilestore {
|
||||
path.file_name().and_then(|name| name.to_str())
|
||||
}
|
||||
|
||||
fn is_file(&self, path: &str) -> bool;
|
||||
fn is_file(&self, path: &str) -> Result<bool, FilestoreError>;
|
||||
|
||||
fn is_dir(&self, path: &str) -> bool {
|
||||
!self.is_file(path)
|
||||
fn is_dir(&self, path: &str) -> Result<bool, FilestoreError> {
|
||||
Ok(!self.is_file(path)?)
|
||||
}
|
||||
|
||||
fn exists(&self, path: &str) -> bool;
|
||||
fn exists(&self, path: &str) -> Result<bool, FilestoreError>;
|
||||
|
||||
fn file_size(&self, path: &str) -> Result<u64, FilestoreError>;
|
||||
|
||||
/// This special function is the CFDP specific abstraction to verify the checksum of a file.
|
||||
/// This allows to keep OS specific details like reading the whole file in the most efficient
|
||||
@ -160,7 +162,7 @@ pub mod std_mod {
|
||||
|
||||
impl VirtualFilestore for NativeFilestore {
|
||||
fn create_file(&self, file_path: &str) -> Result<(), FilestoreError> {
|
||||
if self.exists(file_path) {
|
||||
if self.exists(file_path)? {
|
||||
return Err(FilestoreError::FileAlreadyExists);
|
||||
}
|
||||
File::create(file_path)?;
|
||||
@ -168,10 +170,10 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
fn remove_file(&self, file_path: &str) -> Result<(), FilestoreError> {
|
||||
if !self.exists(file_path) {
|
||||
if !self.exists(file_path)? {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
if !self.is_file(file_path) {
|
||||
if !self.is_file(file_path)? {
|
||||
return Err(FilestoreError::IsNotFile);
|
||||
}
|
||||
fs::remove_file(file_path)?;
|
||||
@ -179,10 +181,10 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
fn truncate_file(&self, file_path: &str) -> Result<(), FilestoreError> {
|
||||
if !self.exists(file_path) {
|
||||
if !self.exists(file_path)? {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
if !self.is_file(file_path) {
|
||||
if !self.is_file(file_path)? {
|
||||
return Err(FilestoreError::IsNotFile);
|
||||
}
|
||||
OpenOptions::new()
|
||||
@ -201,10 +203,10 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
fn remove_dir(&self, dir_path: &str, all: bool) -> Result<(), FilestoreError> {
|
||||
if !self.exists(dir_path) {
|
||||
if !self.exists(dir_path)? {
|
||||
return Err(FilestoreError::DirDoesNotExist);
|
||||
}
|
||||
if !self.is_dir(dir_path) {
|
||||
if !self.is_dir(dir_path)? {
|
||||
return Err(FilestoreError::IsNotDirectory);
|
||||
}
|
||||
if !all {
|
||||
@ -229,10 +231,10 @@ pub mod std_mod {
|
||||
}
|
||||
.into());
|
||||
}
|
||||
if !self.exists(file_name) {
|
||||
if !self.exists(file_name)? {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
if !self.is_file(file_name) {
|
||||
if !self.is_file(file_name)? {
|
||||
return Err(FilestoreError::IsNotFile);
|
||||
}
|
||||
let mut file = File::open(file_name)?;
|
||||
@ -242,10 +244,10 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
fn write_data(&self, file: &str, offset: u64, buf: &[u8]) -> Result<(), FilestoreError> {
|
||||
if !self.exists(file) {
|
||||
if !self.exists(file)? {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
if !self.is_file(file) {
|
||||
if !self.is_file(file)? {
|
||||
return Err(FilestoreError::IsNotFile);
|
||||
}
|
||||
let mut file = OpenOptions::new().write(true).open(file)?;
|
||||
@ -254,17 +256,28 @@ pub mod std_mod {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_file(&self, path: &str) -> bool {
|
||||
let path = Path::new(path);
|
||||
path.is_file()
|
||||
fn is_file(&self, str_path: &str) -> Result<bool, FilestoreError> {
|
||||
let path = Path::new(str_path);
|
||||
if !self.exists(str_path)? {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
Ok(path.is_file())
|
||||
}
|
||||
|
||||
fn exists(&self, path: &str) -> bool {
|
||||
fn exists(&self, path: &str) -> Result<bool, FilestoreError> {
|
||||
let path = Path::new(path);
|
||||
if !path.exists() {
|
||||
return false;
|
||||
Ok(self.exists_internal(path))
|
||||
}
|
||||
|
||||
fn file_size(&self, str_path: &str) -> Result<u64, FilestoreError> {
|
||||
let path = Path::new(str_path);
|
||||
if !self.exists_internal(path) {
|
||||
return Err(FilestoreError::FileDoesNotExist);
|
||||
}
|
||||
true
|
||||
if !path.is_file() {
|
||||
return Err(FilestoreError::IsNotFile);
|
||||
}
|
||||
Ok(path.metadata()?.len())
|
||||
}
|
||||
|
||||
fn checksum_verify(
|
||||
@ -324,6 +337,13 @@ pub mod std_mod {
|
||||
}
|
||||
Ok(checksum)
|
||||
}
|
||||
|
||||
fn exists_internal(&self, path: &Path) -> bool {
|
||||
if !path.exists() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,32 +370,34 @@ mod tests {
|
||||
assert!(result.is_ok());
|
||||
let path = Path::new(&file_path);
|
||||
assert!(path.exists());
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_native_fs_file_exists() {
|
||||
let tmpdir = tempdir().expect("creating tmpdir failed");
|
||||
let file_path = tmpdir.path().join("test.txt");
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.create_file(file_path.to_str().expect("getting str for file failed"))
|
||||
.unwrap();
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_native_fs_dir_exists() {
|
||||
let tmpdir = tempdir().expect("creating tmpdir failed");
|
||||
let dir_path = tmpdir.path().join("testdir");
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.create_dir(dir_path.to_str().expect("getting str for file failed"))
|
||||
.unwrap();
|
||||
assert!(NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.is_dir(dir_path.as_path().to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
assert!(NATIVE_FS
|
||||
.is_dir(dir_path.as_path().to_str().unwrap())
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -385,23 +407,23 @@ mod tests {
|
||||
NATIVE_FS
|
||||
.create_file(file_path.to_str().expect("getting str for file failed"))
|
||||
.expect("creating file failed");
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.remove_file(file_path.to_str().unwrap())
|
||||
.expect("removing file failed");
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_native_fs_write() {
|
||||
let tmpdir = tempdir().expect("creating tmpdir failed");
|
||||
let file_path = tmpdir.path().join("test.txt");
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.create_file(file_path.to_str().expect("getting str for file failed"))
|
||||
.unwrap();
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()).unwrap());
|
||||
println!("{}", file_path.to_str().unwrap());
|
||||
let write_data = "hello world\n";
|
||||
NATIVE_FS
|
||||
@ -415,12 +437,12 @@ mod tests {
|
||||
fn test_basic_native_fs_read() {
|
||||
let tmpdir = tempdir().expect("creating tmpdir failed");
|
||||
let file_path = tmpdir.path().join("test.txt");
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.create_file(file_path.to_str().expect("getting str for file failed"))
|
||||
.unwrap();
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(file_path.to_str().unwrap()).unwrap());
|
||||
assert!(NATIVE_FS.is_file(file_path.to_str().unwrap()).unwrap());
|
||||
println!("{}", file_path.to_str().unwrap());
|
||||
let write_data = "hello world\n";
|
||||
NATIVE_FS
|
||||
@ -449,15 +471,15 @@ mod tests {
|
||||
fn test_remove_dir() {
|
||||
let tmpdir = tempdir().expect("creating tmpdir failed");
|
||||
let dir_path = tmpdir.path().join("testdir");
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.create_dir(dir_path.to_str().expect("getting str for file failed"))
|
||||
.unwrap();
|
||||
assert!(NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
NATIVE_FS
|
||||
.remove_dir(dir_path.to_str().unwrap(), false)
|
||||
.unwrap();
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -544,7 +566,7 @@ mod tests {
|
||||
.unwrap();
|
||||
let result = NATIVE_FS.remove_dir(dir_path.to_str().unwrap(), true);
|
||||
assert!(result.is_ok());
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()));
|
||||
assert!(!NATIVE_FS.exists(dir_path.to_str().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -540,6 +540,14 @@ pub mod alloc_mod {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn has_source_file(&self) -> bool {
|
||||
self.static_fields.source_file_len > 0
|
||||
}
|
||||
|
||||
pub fn has_dest_file(&self) -> bool {
|
||||
self.static_fields.dest_file_len > 0
|
||||
}
|
||||
|
||||
pub fn source_file(&self) -> Result<&str, Utf8Error> {
|
||||
core::str::from_utf8(
|
||||
&self.static_fields.source_file_buf[0..self.static_fields.source_file_len],
|
||||
|
@ -1,13 +1,22 @@
|
||||
use core::str::Utf8Error;
|
||||
|
||||
use spacepackets::{
|
||||
cfdp::{pdu::FileDirectiveType, PduType},
|
||||
util::UnsignedByteField,
|
||||
cfdp::{
|
||||
lv::Lv,
|
||||
pdu::{
|
||||
metadata::{MetadataGenericParams, MetadataPduCreator},
|
||||
CommonPduConfig, FileDirectiveType, PduHeader,
|
||||
},
|
||||
Direction, LargeFileFlag, PduType,
|
||||
},
|
||||
util::{UnsignedByteField, UnsignedEnum},
|
||||
ByteConversionError,
|
||||
};
|
||||
|
||||
use crate::seq_count::SequenceCountProvider;
|
||||
|
||||
use super::{
|
||||
filestore::VirtualFilestore,
|
||||
filestore::{FilestoreError, VirtualFilestore},
|
||||
request::{ReadablePutRequest, StaticPutRequestCacher},
|
||||
user::CfdpUser,
|
||||
LocalEntityConfig, PacketInfo, PacketTarget, PduSendProvider, RemoteEntityConfig,
|
||||
@ -30,12 +39,13 @@ pub enum TransactionStep {
|
||||
NoticeOfCompletion = 10,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FileParams {
|
||||
pub progress: usize,
|
||||
pub segment_len: usize,
|
||||
pub crc32: Option<[u8; 4]>,
|
||||
//pub crc32: Option<[u8; 4]>,
|
||||
pub metadata_only: bool,
|
||||
pub file_size: usize,
|
||||
pub file_size: u64,
|
||||
pub no_eof: bool,
|
||||
}
|
||||
|
||||
@ -76,6 +86,12 @@ pub enum SourceError {
|
||||
PutRequestAlreadyActive,
|
||||
#[error("error caching put request")]
|
||||
PutRequestCaching(ByteConversionError),
|
||||
#[error("filestore error: {0}")]
|
||||
FilestoreError(#[from] FilestoreError),
|
||||
#[error("source file does not have valid UTF8 format: {0}")]
|
||||
SourceFileNotValidUtf8(Utf8Error),
|
||||
#[error("destination file does not have valid UTF8 format: {0}")]
|
||||
DestFileNotValidUtf8(Utf8Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
@ -99,7 +115,12 @@ pub struct SourceHandler<
|
||||
remote_cfg_table: RemoteCfgTable,
|
||||
vfs: Vfs,
|
||||
state_helper: StateHelper,
|
||||
// Transfer related state information
|
||||
tstate: Option<TransferState>,
|
||||
// File specific transfer fields
|
||||
fparams: FileParams,
|
||||
// PDU configuration is cached so it can be re-used for all PDUs generated for file transfers.
|
||||
pdu_conf: CommonPduConfig,
|
||||
seq_count_provider: SeqCountProvider,
|
||||
}
|
||||
|
||||
@ -127,6 +148,8 @@ impl<
|
||||
put_request_cacher,
|
||||
state_helper: Default::default(),
|
||||
tstate: Default::default(),
|
||||
fparams: Default::default(),
|
||||
pdu_conf: Default::default(),
|
||||
seq_count_provider,
|
||||
}
|
||||
}
|
||||
@ -203,10 +226,6 @@ impl<
|
||||
}
|
||||
self.put_request_cacher.set(put_request)?;
|
||||
self.state_helper.state = super::State::Busy;
|
||||
let source_file = self.put_request_cacher.source_file().unwrap();
|
||||
if !self.vfs.exists(source_file) {
|
||||
// TODO: Specific error.
|
||||
}
|
||||
let remote_cfg = self.remote_cfg_table.get(
|
||||
self.put_request_cacher
|
||||
.static_fields
|
||||
@ -218,7 +237,6 @@ impl<
|
||||
}
|
||||
let remote_cfg = remote_cfg.unwrap();
|
||||
self.state_helper.num_packets_ready = 0;
|
||||
//self.tstate.remote_cfg = Some(*remote_cfg);
|
||||
let transmission_mode = if self.put_request_cacher.static_fields.trans_mode.is_some() {
|
||||
self.put_request_cacher.static_fields.trans_mode.unwrap()
|
||||
} else {
|
||||
@ -252,12 +270,130 @@ impl<
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn transmission_mode(&self) {}
|
||||
pub fn transmission_mode(&self) -> Option<super::TransmissionMode> {
|
||||
self.tstate.map(|v| v.transmission_mode)
|
||||
}
|
||||
|
||||
fn fsm_busy(&mut self, cfdp_user: &mut impl CfdpUser) -> Result<u32, SourceError> {
|
||||
if self.state_helper.step == TransactionStep::Idle {
|
||||
self.state_helper.step = TransactionStep::TransactionStart;
|
||||
}
|
||||
if self.state_helper.step == TransactionStep::TransactionStart {
|
||||
self.handle_transaction_start(cfdp_user)?;
|
||||
self.state_helper.step = TransactionStep::SendingMetadata;
|
||||
}
|
||||
if self.state_helper.step == TransactionStep::SendingMetadata {
|
||||
self.prepare_and_send_metadata_pdu();
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn handle_transaction_start(
|
||||
&mut self,
|
||||
cfdp_user: &mut impl CfdpUser,
|
||||
) -> Result<(), SourceError> {
|
||||
let tstate = &self.tstate.expect("transfer state unexpectedly empty");
|
||||
if !self.put_request_cacher.has_source_file() {
|
||||
self.fparams.metadata_only = true;
|
||||
self.fparams.no_eof = true;
|
||||
} else {
|
||||
let source_file = self
|
||||
.put_request_cacher
|
||||
.source_file()
|
||||
.map_err(SourceError::SourceFileNotValidUtf8)?;
|
||||
if !self.vfs.exists(source_file)? {
|
||||
return Err(SourceError::FilestoreError(
|
||||
FilestoreError::FileDoesNotExist,
|
||||
));
|
||||
}
|
||||
// We expect the destination file path to consist of valid UTF-8 characters as well.
|
||||
self.put_request_cacher
|
||||
.dest_file()
|
||||
.map_err(SourceError::DestFileNotValidUtf8)?;
|
||||
if self.vfs.file_size(source_file)? > u32::MAX as u64 {
|
||||
self.pdu_conf.file_flag = LargeFileFlag::Large
|
||||
} else {
|
||||
self.pdu_conf.file_flag = LargeFileFlag::Normal
|
||||
}
|
||||
}
|
||||
// Both the source entity and destination entity ID field must have the same size.
|
||||
// We use the larger of either the Put Request destination ID or the local entity ID
|
||||
// as the size for the new entity IDs.
|
||||
let larger_entity_width = core::cmp::max(
|
||||
self.local_cfg.id.size(),
|
||||
self.put_request_cacher.static_fields.destination_id.size(),
|
||||
);
|
||||
let create_id = |cached_id: &UnsignedByteField| {
|
||||
if larger_entity_width != cached_id.size() {
|
||||
UnsignedByteField::new(larger_entity_width, cached_id.value_const())
|
||||
} else {
|
||||
self.local_cfg.id
|
||||
}
|
||||
};
|
||||
self.pdu_conf
|
||||
.set_source_and_dest_id(
|
||||
create_id(&self.local_cfg.id),
|
||||
create_id(&self.put_request_cacher.static_fields.destination_id),
|
||||
)
|
||||
.unwrap();
|
||||
// Set up other PDU configuration fields.
|
||||
self.pdu_conf.direction = Direction::TowardsReceiver;
|
||||
self.pdu_conf.crc_flag = tstate.remote_cfg.crc_on_transmission_by_default.into();
|
||||
self.pdu_conf.transaction_seq_num = *tstate.transaction_id.seq_num();
|
||||
self.pdu_conf.trans_mode = tstate.transmission_mode;
|
||||
|
||||
cfdp_user.transaction_indication(&tstate.transaction_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_and_send_metadata_pdu(&self) {
|
||||
let tstate = &self.tstate.expect("transfer state unexpectedly empty");
|
||||
if self.fparams.metadata_only {
|
||||
let metadata_params = MetadataGenericParams::new(
|
||||
tstate.closure_requested,
|
||||
tstate.remote_cfg.default_crc_type,
|
||||
self.fparams.file_size,
|
||||
);
|
||||
let metadata_pdu = MetadataPduCreator::new(
|
||||
PduHeader::new_no_file_data(self.pdu_conf, 0),
|
||||
metadata_params,
|
||||
Lv::new_empty(),
|
||||
Lv::new_empty(),
|
||||
&[],
|
||||
);
|
||||
//self.pdu_sender.send_pdu(pdu_type, file_directive_type, raw_pdu)
|
||||
}
|
||||
/*
|
||||
assert self._put_req is not None
|
||||
options = []
|
||||
if self._put_req.metadata_only:
|
||||
params = MetadataParams(
|
||||
closure_requested=self._params.closure_requested,
|
||||
checksum_type=self._crc_helper.checksum_type,
|
||||
file_size=0,
|
||||
dest_file_name=None,
|
||||
source_file_name=None,
|
||||
)
|
||||
else:
|
||||
# Funny name.
|
||||
params = self._prepare_metadata_base_params_with_metadata()
|
||||
if self._put_req.fs_requests is not None:
|
||||
for fs_request in self._put_req.fs_requests:
|
||||
options.append(fs_request)
|
||||
if self._put_req.fault_handler_overrides is not None:
|
||||
for fh_override in self._put_req.fault_handler_overrides:
|
||||
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_nak_pdu(&mut self) {}
|
||||
|
Loading…
Reference in New Issue
Block a user