dest handler changes missing
This commit is contained in:
@ -54,6 +54,7 @@ serde = ["dep:serde", "spacepackets/serde"]
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
log = "0.4"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
fmt::Debug,
|
||||||
fs::OpenOptions,
|
fs::OpenOptions,
|
||||||
io::Write,
|
io::{self, ErrorKind, Write},
|
||||||
|
net::{SocketAddr, ToSocketAddrs, UdpSocket},
|
||||||
sync::{atomic::AtomicBool, mpsc, Arc},
|
sync::{atomic::AtomicBool, mpsc, Arc},
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -8,6 +10,7 @@ use std::{
|
|||||||
|
|
||||||
use cfdp::{
|
use cfdp::{
|
||||||
dest::DestinationHandler,
|
dest::DestinationHandler,
|
||||||
|
determine_packet_target,
|
||||||
filestore::NativeFilestore,
|
filestore::NativeFilestore,
|
||||||
request::{PutRequestOwned, StaticPutRequestCacher},
|
request::{PutRequestOwned, StaticPutRequestCacher},
|
||||||
source::SourceHandler,
|
source::SourceHandler,
|
||||||
@ -15,8 +18,9 @@ use cfdp::{
|
|||||||
EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo, RemoteEntityConfig,
|
EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo, RemoteEntityConfig,
|
||||||
StdCheckTimerCreator, TransactionId, UserFaultHookProvider,
|
StdCheckTimerCreator, TransactionId, UserFaultHookProvider,
|
||||||
};
|
};
|
||||||
|
use log::{info, warn};
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
cfdp::{ChecksumType, ConditionCode, TransmissionMode},
|
cfdp::{pdu::PduError, ChecksumType, ConditionCode, TransmissionMode},
|
||||||
seq_count::SeqCountProviderSyncU16,
|
seq_count::SeqCountProviderSyncU16,
|
||||||
util::UnsignedByteFieldU16,
|
util::UnsignedByteFieldU16,
|
||||||
};
|
};
|
||||||
@ -155,6 +159,90 @@ impl CfdpUser for ExampleCfdpUser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct UdpServer {
|
||||||
|
pub socket: UdpSocket,
|
||||||
|
recv_buf: Vec<u8>,
|
||||||
|
sender_addr: Option<SocketAddr>,
|
||||||
|
src_tx: mpsc::SyncSender<Vec<u8>>,
|
||||||
|
dest_tx: mpsc::SyncSender<Vec<u8>>,
|
||||||
|
tm_rx: mpsc::Receiver<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum UdpServerError {
|
||||||
|
#[error("nothing was received")]
|
||||||
|
NothingReceived,
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] io::Error),
|
||||||
|
#[error("pdu error: {0}")]
|
||||||
|
Pdu(#[from] PduError),
|
||||||
|
#[error("send error")]
|
||||||
|
Send,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UdpServer {
|
||||||
|
pub fn new<A: ToSocketAddrs>(
|
||||||
|
addr: A,
|
||||||
|
max_recv_size: usize,
|
||||||
|
src_tx: mpsc::SyncSender<Vec<u8>>,
|
||||||
|
dest_tx: mpsc::SyncSender<Vec<u8>>,
|
||||||
|
tm_rx: mpsc::Receiver<Vec<u8>>,
|
||||||
|
) -> Result<Self, io::Error> {
|
||||||
|
let server = Self {
|
||||||
|
socket: UdpSocket::bind(addr)?,
|
||||||
|
recv_buf: vec![0; max_recv_size],
|
||||||
|
tm_rx,
|
||||||
|
src_tx,
|
||||||
|
dest_tx,
|
||||||
|
sender_addr: None,
|
||||||
|
};
|
||||||
|
server.socket.set_nonblocking(true)?;
|
||||||
|
Ok(server)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_recv_tc(&mut self) -> Result<(usize, SocketAddr), UdpServerError> {
|
||||||
|
let res = match self.socket.recv_from(&mut self.recv_buf) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut {
|
||||||
|
Err(UdpServerError::NothingReceived)
|
||||||
|
} else {
|
||||||
|
Err(e.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let (num_bytes, from) = res;
|
||||||
|
self.sender_addr = Some(from);
|
||||||
|
let packet_target = determine_packet_target(&self.recv_buf)?;
|
||||||
|
match packet_target {
|
||||||
|
cfdp::PacketTarget::SourceEntity => {
|
||||||
|
self.src_tx
|
||||||
|
.send(self.recv_buf[0..num_bytes].to_vec())
|
||||||
|
.map_err(|_| UdpServerError::Send)?;
|
||||||
|
}
|
||||||
|
cfdp::PacketTarget::DestEntity => {
|
||||||
|
self.dest_tx
|
||||||
|
.send(self.recv_buf[0..num_bytes].to_vec())
|
||||||
|
.map_err(|_| UdpServerError::Send)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_tm(&mut self, socket: &UdpSocket, recv_addr: &SocketAddr) {
|
||||||
|
while let Ok(tm) = self.tm_rx.try_recv() {
|
||||||
|
let result = socket.send_to(&tm, recv_addr);
|
||||||
|
if let Err(e) = result {
|
||||||
|
warn!("Sending TM with UDP socket failed: {e}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last_sender(&self) -> Option<SocketAddr> {
|
||||||
|
self.sender_addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Simplified event handling using atomic signals.
|
// Simplified event handling using atomic signals.
|
||||||
let stop_signal_source = Arc::new(AtomicBool::new(false));
|
let stop_signal_source = Arc::new(AtomicBool::new(false));
|
||||||
|
13
src/dest.rs
13
src/dest.rs
@ -860,7 +860,11 @@ mod tests {
|
|||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
cfdp::{
|
cfdp::{
|
||||||
lv::Lv,
|
lv::Lv,
|
||||||
pdu::{finished::FinishedPduReader, metadata::MetadataPduCreator, WritablePduPacket},
|
pdu::{
|
||||||
|
finished::{self, FinishedPduReader},
|
||||||
|
metadata::MetadataPduCreator,
|
||||||
|
WritablePduPacket,
|
||||||
|
},
|
||||||
ChecksumType, TransmissionMode,
|
ChecksumType, TransmissionMode,
|
||||||
},
|
},
|
||||||
util::{UbfU16, UnsignedByteFieldU16},
|
util::{UbfU16, UnsignedByteFieldU16},
|
||||||
@ -1565,6 +1569,13 @@ mod tests {
|
|||||||
Some(FileDirectiveType::FinishedPdu)
|
Some(FileDirectiveType::FinishedPdu)
|
||||||
);
|
);
|
||||||
let finished_pdu = FinishedPduReader::from_bytes(&sent_pdu.raw_pdu).unwrap();
|
let finished_pdu = FinishedPduReader::from_bytes(&sent_pdu.raw_pdu).unwrap();
|
||||||
|
assert_eq!(finished_pdu.file_status(), FileStatus::Retained);
|
||||||
|
assert_eq!(
|
||||||
|
finished_pdu.condition_code(),
|
||||||
|
ConditionCode::CheckLimitReached
|
||||||
|
);
|
||||||
|
assert_eq!(finished_pdu.delivery_code(), DeliveryCode::Incomplete);
|
||||||
assert!(tb.handler.pdu_sender.queue_empty());
|
assert!(tb.handler.pdu_sender.queue_empty());
|
||||||
|
tb.expected_full_data = faulty_file_data.to_vec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/lib.rs
21
src/lib.rs
@ -724,19 +724,20 @@ impl PduProvider for DummyPduProvider {
|
|||||||
pub struct PacketInfo<'raw_packet> {
|
pub struct PacketInfo<'raw_packet> {
|
||||||
pdu_type: PduType,
|
pdu_type: PduType,
|
||||||
file_directive_type: Option<FileDirectiveType>,
|
file_directive_type: Option<FileDirectiveType>,
|
||||||
//target: PacketTarget,
|
|
||||||
raw_packet: &'raw_packet [u8],
|
raw_packet: &'raw_packet [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn determine_packet_target(
|
pub fn determine_packet_target(raw_pdu: &[u8]) -> Result<PacketTarget, PduError> {
|
||||||
file_directive_type: Option<FileDirectiveType>,
|
let (header, header_len) = PduHeader::from_bytes(raw_pdu)?;
|
||||||
raw_pdu: &[u8],
|
if header.pdu_type() == PduType::FileData {
|
||||||
) -> Result<PacketTarget, PduError> {
|
|
||||||
if file_directive_type.is_none() {
|
|
||||||
return Ok(PacketTarget::DestEntity);
|
return Ok(PacketTarget::DestEntity);
|
||||||
}
|
}
|
||||||
let (_, header_len) = PduHeader::from_bytes(raw_pdu)?;
|
let file_directive_type = FileDirectiveType::try_from(raw_pdu[header_len]).map_err(|_| {
|
||||||
let file_directive_type = file_directive_type.unwrap();
|
PduError::InvalidDirectiveType {
|
||||||
|
found: raw_pdu[header_len],
|
||||||
|
expected: None,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
let packet_target =
|
let packet_target =
|
||||||
match file_directive_type {
|
match file_directive_type {
|
||||||
// Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
|
// Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
|
||||||
@ -823,7 +824,7 @@ impl PduProvider for PacketInfo<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn packet_target(&self) -> Result<PacketTarget, PduError> {
|
fn packet_target(&self) -> Result<PacketTarget, PduError> {
|
||||||
determine_packet_target(self.file_directive_type, self.raw_packet)
|
determine_packet_target(self.raw_packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,7 +871,7 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn packet_target(&self) -> Result<PacketTarget, PduError> {
|
fn packet_target(&self) -> Result<PacketTarget, PduError> {
|
||||||
determine_packet_target(self.file_directive_type, &self.pdu)
|
determine_packet_target(&self.pdu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user