add pus distrib test
This commit is contained in:
parent
5ba6766db3
commit
5de211cd40
@ -35,6 +35,7 @@ impl FsrcErrorRaw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct SimpleStdErrorHandler {}
|
pub struct SimpleStdErrorHandler {}
|
||||||
|
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
|
@ -2,20 +2,20 @@ use crate::error::FsrcErrorHandler;
|
|||||||
use crate::tmtc::{ReceivesTc, FROM_BYTES_SLICE_TOO_SMALL_ERROR, FROM_BYTES_ZEROCOPY_ERROR};
|
use crate::tmtc::{ReceivesTc, FROM_BYTES_SLICE_TOO_SMALL_ERROR, FROM_BYTES_ZEROCOPY_ERROR};
|
||||||
use spacepackets::{CcsdsPacket, PacketError, SpHeader};
|
use spacepackets::{CcsdsPacket, PacketError, SpHeader};
|
||||||
|
|
||||||
pub trait HandlesPacketForApid {
|
pub trait ApidPacketHandler {
|
||||||
fn valid_apids(&self) -> &'static [u16];
|
fn valid_apids(&self) -> &'static [u16];
|
||||||
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]);
|
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]);
|
||||||
fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]);
|
fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CcsdsDistributor {
|
pub struct CcsdsDistributor {
|
||||||
apid_handler: Box<dyn HandlesPacketForApid>,
|
apid_handler: Box<dyn ApidPacketHandler>,
|
||||||
error_handler: Box<dyn FsrcErrorHandler>,
|
error_handler: Box<dyn FsrcErrorHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CcsdsDistributor {
|
impl CcsdsDistributor {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
apid_handler: Box<dyn HandlesPacketForApid>,
|
apid_handler: Box<dyn ApidPacketHandler>,
|
||||||
error_handler: Box<dyn FsrcErrorHandler>,
|
error_handler: Box<dyn FsrcErrorHandler>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
CcsdsDistributor {
|
CcsdsDistributor {
|
||||||
@ -52,9 +52,102 @@ impl ReceivesTc for CcsdsDistributor {
|
|||||||
let valid_apids = self.apid_handler.valid_apids();
|
let valid_apids = self.apid_handler.valid_apids();
|
||||||
for &valid_apid in valid_apids {
|
for &valid_apid in valid_apids {
|
||||||
if valid_apid == apid {
|
if valid_apid == apid {
|
||||||
self.apid_handler.handle_known_apid(&sp_header, tm_raw);
|
return self.apid_handler.handle_known_apid(&sp_header, tm_raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.apid_handler.handle_unknown_apid(&sp_header, tm_raw);
|
self.apid_handler.handle_unknown_apid(&sp_header, tm_raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::error::SimpleStdErrorHandler;
|
||||||
|
use crate::tmtc::ccsds_distrib::{ApidPacketHandler, CcsdsDistributor};
|
||||||
|
use spacepackets::tc::PusTc;
|
||||||
|
use spacepackets::CcsdsPacket;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct BasicApidHandler {
|
||||||
|
pub known_packet_queue: Arc<Mutex<VecDeque<(u16, Vec<u8>)>>>,
|
||||||
|
pub unknown_packet_queue: Arc<Mutex<VecDeque<(u16, Vec<u8>)>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApidPacketHandler for BasicApidHandler {
|
||||||
|
fn valid_apids(&self) -> &'static [u16] {
|
||||||
|
&[0x000, 0x002]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
vec.extend_from_slice(tc_raw);
|
||||||
|
self.known_packet_queue
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push_back((sp_header.apid(), vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
vec.extend_from_slice(tc_raw);
|
||||||
|
self.unknown_packet_queue
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push_back((sp_header.apid(), vec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_distribs_known_apid() {
|
||||||
|
let known_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let unknown_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let apid_handler = BasicApidHandler {
|
||||||
|
known_packet_queue: known_packet_queue.clone(),
|
||||||
|
unknown_packet_queue: unknown_packet_queue.clone(),
|
||||||
|
};
|
||||||
|
let error_handler = SimpleStdErrorHandler {};
|
||||||
|
let mut ccsds_distrib =
|
||||||
|
CcsdsDistributor::new(Box::new(apid_handler), Box::new(error_handler));
|
||||||
|
let mut sph = SpHeader::tc(0x002, 0x34, 0).unwrap();
|
||||||
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
|
let mut test_buf: [u8; 32] = [0; 32];
|
||||||
|
pus_tc
|
||||||
|
.write_to(test_buf.as_mut_slice())
|
||||||
|
.expect("Error writing TC to buffer");
|
||||||
|
ccsds_distrib.pass_tc(&test_buf);
|
||||||
|
let recvd = known_packet_queue.lock().unwrap().pop_front();
|
||||||
|
assert!(unknown_packet_queue.lock().unwrap().is_empty());
|
||||||
|
assert!(recvd.is_some());
|
||||||
|
let (apid, packet) = recvd.unwrap();
|
||||||
|
assert_eq!(apid, 0x002);
|
||||||
|
assert_eq!(packet.as_slice(), test_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_distribs_unknown_apid() {
|
||||||
|
let known_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let unknown_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let apid_handler = BasicApidHandler {
|
||||||
|
known_packet_queue: known_packet_queue.clone(),
|
||||||
|
unknown_packet_queue: unknown_packet_queue.clone(),
|
||||||
|
};
|
||||||
|
let error_handler = SimpleStdErrorHandler {};
|
||||||
|
let mut ccsds_distrib =
|
||||||
|
CcsdsDistributor::new(Box::new(apid_handler), Box::new(error_handler));
|
||||||
|
let mut sph = SpHeader::tc(0x004, 0x34, 0).unwrap();
|
||||||
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
|
let mut test_buf: [u8; 32] = [0; 32];
|
||||||
|
pus_tc
|
||||||
|
.write_to(test_buf.as_mut_slice())
|
||||||
|
.expect("Error writing TC to buffer");
|
||||||
|
ccsds_distrib.pass_tc(&test_buf);
|
||||||
|
let recvd = unknown_packet_queue.lock().unwrap().pop_front();
|
||||||
|
assert!(known_packet_queue.lock().unwrap().is_empty());
|
||||||
|
assert!(recvd.is_some());
|
||||||
|
let (apid, packet) = recvd.unwrap();
|
||||||
|
assert_eq!(apid, 0x004);
|
||||||
|
assert_eq!(packet.as_slice(), test_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use crate::error::{FsrcErrorRaw, FsrcGroupIds};
|
use crate::error::{FsrcErrorRaw, FsrcGroupIds};
|
||||||
use spacepackets::ecss::PusError;
|
|
||||||
use spacepackets::tc::PusTc;
|
|
||||||
use spacepackets::{PacketError, SpHeader};
|
use spacepackets::{PacketError, SpHeader};
|
||||||
|
|
||||||
pub mod ccsds_distrib;
|
pub mod ccsds_distrib;
|
||||||
@ -32,72 +30,3 @@ pub trait ReceivesTc {
|
|||||||
pub trait ReceivesCcsdsTc {
|
pub trait ReceivesCcsdsTc {
|
||||||
fn pass_ccsds(&mut self, header: &SpHeader, tc_raw: &[u8]) -> Result<(), PacketError>;
|
fn pass_ccsds(&mut self, header: &SpHeader, tc_raw: &[u8]) -> Result<(), PacketError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReceivesPusTc {
|
|
||||||
fn pass_pus(&mut self, pus_tc: &PusTc) -> Result<(), PusError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::error::SimpleStdErrorHandler;
|
|
||||||
use crate::tmtc::ccsds_distrib::{CcsdsDistributor, HandlesPacketForApid};
|
|
||||||
use spacepackets::CcsdsPacket;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct ApidHandler {
|
|
||||||
known_packet_queue: Arc<Mutex<VecDeque<(u16, Vec<u8>)>>>,
|
|
||||||
unknown_packet_queue: Arc<Mutex<VecDeque<(u16, Vec<u8>)>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HandlesPacketForApid for ApidHandler {
|
|
||||||
fn valid_apids(&self) -> &'static [u16] {
|
|
||||||
&[0x000, 0x002]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
|
||||||
let mut vec = Vec::new();
|
|
||||||
vec.extend_from_slice(tc_raw);
|
|
||||||
self.known_packet_queue
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push_back((sp_header.apid(), vec));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
|
||||||
let mut vec = Vec::new();
|
|
||||||
vec.extend_from_slice(tc_raw);
|
|
||||||
self.unknown_packet_queue
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push_back((sp_header.apid(), vec));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_distribs_known_apid() {
|
|
||||||
let known_packet_queue = Arc::new(Mutex::default());
|
|
||||||
let unknown_packet_queue = Arc::new(Mutex::default());
|
|
||||||
let apid_handler = ApidHandler {
|
|
||||||
known_packet_queue: known_packet_queue.clone(),
|
|
||||||
unknown_packet_queue: unknown_packet_queue.clone(),
|
|
||||||
};
|
|
||||||
let error_handler = SimpleStdErrorHandler {};
|
|
||||||
let mut ccsds_distrib =
|
|
||||||
CcsdsDistributor::new(Box::new(apid_handler), Box::new(error_handler));
|
|
||||||
let mut sph = SpHeader::tc(0x002, 0x34, 0).unwrap();
|
|
||||||
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
|
||||||
let mut test_buf: [u8; 32] = [0; 32];
|
|
||||||
pus_tc
|
|
||||||
.write_to(test_buf.as_mut_slice())
|
|
||||||
.expect("Error writing TC to buffer");
|
|
||||||
ccsds_distrib.pass_tc(&test_buf);
|
|
||||||
let recvd = known_packet_queue.lock().unwrap().pop_front();
|
|
||||||
assert!(recvd.is_some());
|
|
||||||
let (apid, packet) = recvd.unwrap();
|
|
||||||
assert_eq!(apid, 0x002);
|
|
||||||
assert_eq!(packet.as_slice(), test_buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::error::FsrcErrorHandler;
|
use crate::error::FsrcErrorHandler;
|
||||||
use crate::tmtc::{ReceivesCcsdsTc, ReceivesPusTc, ReceivesTc};
|
use crate::tmtc::{ReceivesCcsdsTc, ReceivesTc};
|
||||||
use spacepackets::ecss::{PusError, PusPacket};
|
use spacepackets::ecss::{PusError, PusPacket};
|
||||||
use spacepackets::tc::PusTc;
|
use spacepackets::tc::PusTc;
|
||||||
use spacepackets::{CcsdsPacket, PacketError, SpHeader};
|
use spacepackets::{CcsdsPacket, PacketError, SpHeader};
|
||||||
|
|
||||||
pub trait PusServiceProvider {
|
pub trait PusServiceProvider {
|
||||||
fn get_apid(&self, service: u8) -> u16;
|
fn handle_pus_tc_packet(&mut self, service: u8, apid: u16, pus_tc: &PusTc);
|
||||||
fn get_service_handler(&self, service: u8, subservice: u8) -> Box<dyn ReceivesPusTc>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PusDistributor {
|
pub struct PusDistributor {
|
||||||
_error_handler: Box<dyn FsrcErrorHandler>,
|
|
||||||
service_provider: Box<dyn PusServiceProvider>,
|
service_provider: Box<dyn PusServiceProvider>,
|
||||||
|
error_handler: Box<dyn FsrcErrorHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReceivesTc for PusDistributor {
|
impl ReceivesTc for PusDistributor {
|
||||||
@ -40,15 +39,106 @@ impl ReceivesCcsdsTc for PusDistributor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut srv_provider = self
|
self.service_provider
|
||||||
.service_provider
|
.handle_pus_tc_packet(tc.service(), tc.apid(), &tc);
|
||||||
.get_service_handler(tc.service(), tc.subservice());
|
|
||||||
let apid = self.service_provider.get_apid(tc.service());
|
|
||||||
if apid != tc.apid() {
|
|
||||||
// TODO: Dedicated error
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
srv_provider.pass_pus(&tc).unwrap();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::error::SimpleStdErrorHandler;
|
||||||
|
use crate::tmtc::ccsds_distrib::tests::BasicApidHandler;
|
||||||
|
use crate::tmtc::ccsds_distrib::{ApidPacketHandler, CcsdsDistributor};
|
||||||
|
use spacepackets::tc::PusTc;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
struct PusHandler {
|
||||||
|
pus_queue: Arc<Mutex<VecDeque<(u8, u16, Vec<u8>)>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PusServiceProvider for PusHandler {
|
||||||
|
fn handle_pus_tc_packet(&mut self, service: u8, apid: u16, pus_tc: &PusTc) {
|
||||||
|
let mut vec: Vec<u8> = Vec::new();
|
||||||
|
pus_tc
|
||||||
|
.append_to_vec(&mut vec)
|
||||||
|
.expect("Appending raw PUS TC to vector failed");
|
||||||
|
self.pus_queue
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push_back((service, apid, vec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ApidHandler {
|
||||||
|
pus_distrib: PusDistributor,
|
||||||
|
handler_base: BasicApidHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApidPacketHandler for ApidHandler {
|
||||||
|
fn valid_apids(&self) -> &'static [u16] {
|
||||||
|
&[0x000, 0x002]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
||||||
|
self.handler_base.handle_known_apid(&sp_header, tc_raw);
|
||||||
|
self.pus_distrib
|
||||||
|
.pass_ccsds(&sp_header, tc_raw)
|
||||||
|
.expect("Passing PUS packet failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) {
|
||||||
|
self.handler_base.handle_unknown_apid(&sp_header, tc_raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pus_distribution() {
|
||||||
|
let known_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let unknown_packet_queue = Arc::new(Mutex::default());
|
||||||
|
let pus_queue = Arc::new(Mutex::default());
|
||||||
|
let pus_handler = PusHandler {
|
||||||
|
pus_queue: pus_queue.clone(),
|
||||||
|
};
|
||||||
|
let handler_base = BasicApidHandler {
|
||||||
|
known_packet_queue: known_packet_queue.clone(),
|
||||||
|
unknown_packet_queue: unknown_packet_queue.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let error_handler = SimpleStdErrorHandler {};
|
||||||
|
let pus_distrib = PusDistributor {
|
||||||
|
service_provider: Box::new(pus_handler),
|
||||||
|
error_handler: Box::new(error_handler),
|
||||||
|
};
|
||||||
|
|
||||||
|
let apid_handler = ApidHandler {
|
||||||
|
pus_distrib,
|
||||||
|
handler_base,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut ccsds_distrib =
|
||||||
|
CcsdsDistributor::new(Box::new(apid_handler), Box::new(error_handler));
|
||||||
|
let mut sph = SpHeader::tc(0x002, 0x34, 0).unwrap();
|
||||||
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
|
let mut test_buf: [u8; 32] = [0; 32];
|
||||||
|
let size = pus_tc
|
||||||
|
.write_to(test_buf.as_mut_slice())
|
||||||
|
.expect("Error writing TC to buffer");
|
||||||
|
let tc_slice = &test_buf[0..size];
|
||||||
|
ccsds_distrib.pass_tc(tc_slice);
|
||||||
|
let recvd_ccsds = known_packet_queue.lock().unwrap().pop_front();
|
||||||
|
assert!(unknown_packet_queue.lock().unwrap().is_empty());
|
||||||
|
assert!(recvd_ccsds.is_some());
|
||||||
|
let (apid, packet) = recvd_ccsds.unwrap();
|
||||||
|
assert_eq!(apid, 0x002);
|
||||||
|
assert_eq!(packet.as_slice(), tc_slice);
|
||||||
|
let recvd_pus = pus_queue.lock().unwrap().pop_front();
|
||||||
|
assert!(recvd_pus.is_some());
|
||||||
|
let (service, apid, tc_raw) = recvd_pus.unwrap();
|
||||||
|
assert_eq!(service, 17);
|
||||||
|
assert_eq!(apid, 0x002);
|
||||||
|
assert_eq!(tc_raw, tc_slice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user