Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and refactoring of PcapStreamer #145

Merged
merged 5 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ members = [
"components/sources/cu_rp_encoder",
"components/tasks/cu_aligner",
"components/tasks/cu_pid",
"components/testing/cu_udp_inject",
"examples/cu_caterpillar",
"examples/cu_config_gen",
"examples/cu_iceoryx2",
Expand Down
27 changes: 26 additions & 1 deletion components/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
You can find a collection of components for Copper in that subtree of the repo.
You can find a collection of components for Copper in that subtree of the repo.

## monitors

UI and interfacing with monitoring systems.

## payloads

Common Message Payloads
Those are for you to use in your tasks. They are used to pass data between tasks.

## sinks

Everything that is the final destination within the Copper DAG like actuation drivers or interfacing with external systems.

## sources

Everything that is creating data entering Copper like sensor drivers or external systems giving inputs to Copper.

## tasks

Internal tasks like algorithms producing an output out of an input.

## testing

Components and libraries that are common to those components for testing them (network injection, mocks etc...)
Empty file removed components/monitors/README.md
Empty file.
3 changes: 0 additions & 3 deletions components/payloads/README.md

This file was deleted.

4 changes: 2 additions & 2 deletions components/sources/cu_hesai/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ uom = { workspace = true }
chrono = { version = "0.4.38" }
socket2 = { version = "0.5.8", features = ["all"] }

# [dev-dependencies]
pcap = "2.2.0"
[dev-dependencies]
cu-udp-inject = { path = "../../testing/cu_udp_inject" }
82 changes: 9 additions & 73 deletions components/sources/cu_hesai/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ impl<'cl> CuSrcTask<'cl> for Xt32 {
Ok(size) => {
let lidar_packet = parser::parse_packet(&buf[..size])
.map_err(|e| CuError::new_with_cause("Failed to parse Hesai UDP packet", e))?;

// this is the reference point for the block timings
let t6 = lidar_packet
.block_ts(&self.reftime)
Expand Down Expand Up @@ -141,81 +140,13 @@ impl<'cl> CuSrcTask<'cl> for Xt32 {
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::parser::Packet;
use chrono::DateTime;
use cu29::cutask::CuMsg;
use pcap::Capture;
use std::net::UdpSocket;
use std::path::Path;
use std::thread::sleep;
use std::time::{Duration, Instant};

/// Small helper to stream a pcap file over UDP
pub struct PcapStreamer {
capture: Capture<pcap::Offline>,
socket: UdpSocket,
target_addr: String,
last_packet_ts: Option<Duration>,
start_instant: Instant,
}

impl PcapStreamer {
pub fn new(file_path: impl AsRef<Path>, target_addr: impl Into<String>) -> Self {
let capture = Capture::from_file(file_path).expect("Failed to open pcap file");
let socket = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind UDP socket");
Self {
capture,
socket,
target_addr: target_addr.into(),
last_packet_ts: None,
start_instant: Instant::now(),
}
}

pub fn send_next(&mut self) -> bool {
// Get the next packet and check for end of stream
let packet = match self.capture.next_packet() {
Ok(packet) => packet,
Err(_) => return false, // End of the stream
};

// Assume 42-byte header (Ethernet + IP + UDP) and an optional 4-byte FCS
let payload_offset = 42;
let fcs_size = 4;

// Check if there's an FCS and slice it off if present
let data_len = if packet.data.len() > payload_offset + fcs_size {
packet.data.len() - fcs_size
} else {
packet.data.len()
};

// Extract only the payload, excluding headers and trailing FCS if present
let payload = &packet.data[payload_offset..data_len];

// Extract the timestamp from the packet
let ts = packet.header.ts;
let packet_ts = Duration::new(ts.tv_sec as u64, ts.tv_usec as u32 * 1000);

if let Some(last_ts) = self.last_packet_ts {
// Sleep to match the delay between packets
let elapsed = self.start_instant.elapsed();
if packet_ts > last_ts {
let wait_time = packet_ts - last_ts;
if elapsed < wait_time {
sleep(wait_time - elapsed);
}
}
}
self.last_packet_ts = Some(packet_ts);

self.socket
.send_to(payload, &self.target_addr)
.expect("Failed to send packet");
true
}
}
use cu_udp_inject::PcapStreamer;

#[test]
fn test_xt32() {
Expand All @@ -235,7 +166,12 @@ mod tests {

xt32.reftime = (datetime, clock.now());

while streamer.send_next() {
// 1076 is the expected payload size for Hesai XT32
const PACKET_SIZE: usize = size_of::<Packet>();
while streamer
.send_next::<PACKET_SIZE>()
.expect("Failed to send next packet")
{
let err = xt32.process(&clock, &mut new_msg);
if let Err(e) = err {
println!("Error: {:?}", e);
Expand Down
120 changes: 100 additions & 20 deletions components/sources/cu_hesai/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,35 +503,115 @@ pub fn generate_default_elevation_calibration() -> [Angle; 32] {
elevations
}

#[cfg(test)]
mod tests {
use super::*;
use crate::parser::{parse_packet, Packet, RefTime};
use cu29::prelude::RobotClock;
use pcap::Capture;

#[test]
fn test_packet() {
// Taken from a real world packet
let packet: [u8; 1122] = [
0xB4, 0x96, 0x91, 0x72, 0x1D, 0x12, 0xEC, 0x9F, 0x0D, 0x01, 0x00, 0x69, 0x08, 0x00,
0x45, 0x00, 0x04, 0x54, 0x57, 0xF2, 0x40, 0x00, 0x40, 0x11, 0xC6, 0xDF, 0x0A, 0xDE,
0x01, 0x0B, 0x0A, 0xDE, 0x01, 0x01, 0x27, 0x10, 0x09, 0x40, 0x04, 0x40, 0x1B, 0xAC,
0xEE, 0xFF, 0x06, 0x01, 0x00, 0x00, 0x20, 0x08, 0x01, 0x04, 0x02, 0x01, 0x8B, 0x77,
0xBB, 0x01, 0x0A, 0xFF, 0xC1, 0x01, 0x0C, 0xFF, 0xC8, 0x01, 0x0B, 0xFF, 0xCD, 0x01,
0x0B, 0xFF, 0xD5, 0x01, 0x0C, 0xFF, 0xDB, 0x01, 0x0C, 0xFF, 0xE3, 0x01, 0x0B, 0xFF,
0xEA, 0x01, 0x0B, 0xFF, 0xF2, 0x01, 0x0B, 0xFF, 0xFA, 0x01, 0x0A, 0xFF, 0x02, 0x02,
0x0A, 0xFF, 0x14, 0x02, 0x06, 0xFF, 0x42, 0x02, 0x06, 0xFF, 0x7C, 0x02, 0x07, 0xFF,
0x8B, 0x02, 0x08, 0xFF, 0x9F, 0x02, 0x0A, 0xFF, 0xAA, 0x02, 0x08, 0xFF, 0xBA, 0x02,
0x09, 0xFF, 0xCE, 0x02, 0x08, 0xFF, 0xDA, 0x02, 0x07, 0xFF, 0xEC, 0x02, 0x07, 0xFF,
0x01, 0x03, 0x0A, 0xFF, 0x1C, 0x03, 0x07, 0xFF, 0x2F, 0x03, 0x05, 0xFF, 0x47, 0x03,
0x07, 0xFF, 0x64, 0x03, 0x07, 0xFF, 0x80, 0x03, 0x07, 0xFF, 0xA4, 0x03, 0x08, 0xFF,
0xBE, 0x03, 0x0A, 0xFF, 0xE5, 0x03, 0x06, 0xFF, 0x15, 0x04, 0x0B, 0xFF, 0x3D, 0x04,
0x06, 0xFF, 0x8B, 0x77, 0xBB, 0x01, 0x0A, 0xFF, 0xC1, 0x01, 0x0C, 0xFF, 0xC8, 0x01,
0x0B, 0xFF, 0xCD, 0x01, 0x0B, 0xFF, 0xD5, 0x01, 0x0C, 0xFF, 0xDB, 0x01, 0x0C, 0xFF,
0xE3, 0x01, 0x0B, 0xFF, 0xEA, 0x01, 0x0B, 0xFF, 0xF2, 0x01, 0x0B, 0xFF, 0xFA, 0x01,
0x0A, 0xFF, 0x02, 0x02, 0x0A, 0xFF, 0x14, 0x02, 0x06, 0xFF, 0x42, 0x02, 0x06, 0xFF,
0x7C, 0x02, 0x07, 0xFF, 0x8B, 0x02, 0x08, 0xFF, 0x9F, 0x02, 0x0A, 0xFF, 0xAA, 0x02,
0x08, 0xFF, 0xBA, 0x02, 0x09, 0xFF, 0xCE, 0x02, 0x08, 0xFF, 0xDA, 0x02, 0x07, 0xFF,
0xEC, 0x02, 0x07, 0xFF, 0x01, 0x03, 0x0A, 0xFF, 0x1C, 0x03, 0x07, 0xFF, 0x2F, 0x03,
0x05, 0xFF, 0x47, 0x03, 0x07, 0xFF, 0x64, 0x03, 0x07, 0xFF, 0x80, 0x03, 0x07, 0xFF,
0xA4, 0x03, 0x08, 0xFF, 0xBE, 0x03, 0x0A, 0xFF, 0xE5, 0x03, 0x06, 0xFF, 0x15, 0x04,
0x0B, 0xFF, 0x3D, 0x04, 0x06, 0xFF, 0x9D, 0x77, 0xBB, 0x01, 0x09, 0xFF, 0xC2, 0x01,
0x0C, 0xFF, 0xC9, 0x01, 0x0C, 0xFF, 0xCF, 0x01, 0x0B, 0xFF, 0xD6, 0x01, 0x0C, 0xFF,
0xDB, 0x01, 0x0B, 0xFF, 0xE3, 0x01, 0x0B, 0xFF, 0xEB, 0x01, 0x0B, 0xFF, 0xF6, 0x01,
0x0B, 0xFF, 0xFC, 0x01, 0x0B, 0xFF, 0x02, 0x02, 0x08, 0xFF, 0x2C, 0x02, 0x06, 0xFF,
0x47, 0x02, 0x06, 0xFF, 0x81, 0x02, 0x08, 0xFF, 0x8D, 0x02, 0x09, 0xFF, 0xA1, 0x02,
0x0A, 0xFF, 0xAC, 0x02, 0x08, 0xFF, 0xBB, 0x02, 0x09, 0xFF, 0xD1, 0x02, 0x08, 0xFF,
0xDE, 0x02, 0x07, 0xFF, 0xF1, 0x02, 0x07, 0xFF, 0x03, 0x03, 0x09, 0xFF, 0x1F, 0x03,
0x07, 0xFF, 0x35, 0x03, 0x06, 0xFF, 0x4B, 0x03, 0x07, 0xFF, 0x68, 0x03, 0x07, 0xFF,
0x82, 0x03, 0x08, 0xFF, 0xA8, 0x03, 0x09, 0xFF, 0xC3, 0x03, 0x0A, 0xFF, 0xE9, 0x03,
0x06, 0xFF, 0x15, 0x04, 0x0B, 0xFF, 0x45, 0x04, 0x07, 0xFF, 0x9D, 0x77, 0xBB, 0x01,
0x09, 0xFF, 0xC2, 0x01, 0x0C, 0xFF, 0xC9, 0x01, 0x0C, 0xFF, 0xCF, 0x01, 0x0B, 0xFF,
0xD6, 0x01, 0x0C, 0xFF, 0xDB, 0x01, 0x0B, 0xFF, 0xE3, 0x01, 0x0B, 0xFF, 0xEB, 0x01,
0x0B, 0xFF, 0xF6, 0x01, 0x0B, 0xFF, 0xFC, 0x01, 0x0B, 0xFF, 0x02, 0x02, 0x08, 0xFF,
0x2C, 0x02, 0x06, 0xFF, 0x47, 0x02, 0x06, 0xFF, 0x81, 0x02, 0x08, 0xFF, 0x8D, 0x02,
0x09, 0xFF, 0xA1, 0x02, 0x0A, 0xFF, 0xAC, 0x02, 0x08, 0xFF, 0xBB, 0x02, 0x09, 0xFF,
0xD1, 0x02, 0x08, 0xFF, 0xDE, 0x02, 0x07, 0xFF, 0xF1, 0x02, 0x07, 0xFF, 0x03, 0x03,
0x09, 0xFF, 0x1F, 0x03, 0x07, 0xFF, 0x35, 0x03, 0x06, 0xFF, 0x4B, 0x03, 0x07, 0xFF,
0x68, 0x03, 0x07, 0xFF, 0x82, 0x03, 0x08, 0xFF, 0xA8, 0x03, 0x09, 0xFF, 0xC3, 0x03,
0x0A, 0xFF, 0xE9, 0x03, 0x06, 0xFF, 0x15, 0x04, 0x0B, 0xFF, 0x45, 0x04, 0x07, 0xFF,
0xAF, 0x77, 0xBE, 0x01, 0x0A, 0xFF, 0xC2, 0x01, 0x0C, 0xFF, 0xC9, 0x01, 0x0B, 0xFF,
0xD0, 0x01, 0x0B, 0xFF, 0xD5, 0x01, 0x0C, 0xFF, 0xDD, 0x01, 0x0C, 0xFF, 0xE4, 0x01,
0x0B, 0xFF, 0xEE, 0x01, 0x0B, 0xFF, 0xF5, 0x01, 0x0B, 0xFF, 0xFC, 0x01, 0x0B, 0xFF,
0x04, 0x02, 0x07, 0xFF, 0x32, 0x02, 0x05, 0xFF, 0x64, 0x02, 0x06, 0xFF, 0x86, 0x02,
0x08, 0xFF, 0x8F, 0x02, 0x08, 0xFF, 0xA2, 0x02, 0x09, 0xFF, 0xAE, 0x02, 0x09, 0xFF,
0xBD, 0x02, 0x08, 0xFF, 0xD1, 0x02, 0x08, 0xFF, 0xDF, 0x02, 0x07, 0xFF, 0xF3, 0x02,
0x07, 0xFF, 0x06, 0x03, 0x09, 0xFF, 0x21, 0x03, 0x07, 0xFF, 0x3A, 0x03, 0x05, 0xFF,
0x4F, 0x03, 0x07, 0xFF, 0x6B, 0x03, 0x08, 0xFF, 0x8A, 0x03, 0x07, 0xFF, 0xAB, 0x03,
0x09, 0xFF, 0xC6, 0x03, 0x08, 0xFF, 0xED, 0x03, 0x07, 0xFF, 0x1C, 0x04, 0x0B, 0xFF,
0x4C, 0x04, 0x07, 0xFF, 0xAF, 0x77, 0xBE, 0x01, 0x0A, 0xFF, 0xC2, 0x01, 0x0C, 0xFF,
0xC9, 0x01, 0x0B, 0xFF, 0xD0, 0x01, 0x0B, 0xFF, 0xD5, 0x01, 0x0C, 0xFF, 0xDD, 0x01,
0x0C, 0xFF, 0xE4, 0x01, 0x0B, 0xFF, 0xEE, 0x01, 0x0B, 0xFF, 0xF5, 0x01, 0x0B, 0xFF,
0xFC, 0x01, 0x0B, 0xFF, 0x04, 0x02, 0x07, 0xFF, 0x32, 0x02, 0x05, 0xFF, 0x64, 0x02,
0x06, 0xFF, 0x86, 0x02, 0x08, 0xFF, 0x8F, 0x02, 0x08, 0xFF, 0xA2, 0x02, 0x09, 0xFF,
0xAE, 0x02, 0x09, 0xFF, 0xBD, 0x02, 0x08, 0xFF, 0xD1, 0x02, 0x08, 0xFF, 0xDF, 0x02,
0x07, 0xFF, 0xF3, 0x02, 0x07, 0xFF, 0x06, 0x03, 0x09, 0xFF, 0x21, 0x03, 0x07, 0xFF,
0x3A, 0x03, 0x05, 0xFF, 0x4F, 0x03, 0x07, 0xFF, 0x6B, 0x03, 0x08, 0xFF, 0x8A, 0x03,
0x07, 0xFF, 0xAB, 0x03, 0x09, 0xFF, 0xC6, 0x03, 0x08, 0xFF, 0xED, 0x03, 0x07, 0xFF,
0x1C, 0x04, 0x0B, 0xFF, 0x4C, 0x04, 0x07, 0xFF, 0xC0, 0x77, 0xBC, 0x01, 0x0B, 0xFF,
0xC3, 0x01, 0x0C, 0xFF, 0xCA, 0x01, 0x0B, 0xFF, 0xD0, 0x01, 0x0B, 0xFF, 0xD7, 0x01,
0x0C, 0xFF, 0xDE, 0x01, 0x0B, 0xFF, 0xE6, 0x01, 0x0B, 0xFF, 0xEE, 0x01, 0x0B, 0xFF,
0xF6, 0x01, 0x0B, 0xFF, 0xFE, 0x01, 0x0B, 0xFF, 0x0F, 0x02, 0x07, 0xFF, 0x37, 0x02,
0x06, 0xFF, 0x72, 0x02, 0x08, 0xFF, 0x89, 0x02, 0x08, 0xFF, 0x91, 0x02, 0x09, 0xFF,
0xA4, 0x02, 0x09, 0xFF, 0xB0, 0x02, 0x09, 0xFF, 0xBF, 0x02, 0x08, 0xFF, 0xD4, 0x02,
0x08, 0xFF, 0xE3, 0x02, 0x07, 0xFF, 0xF5, 0x02, 0x07, 0xFF, 0x08, 0x03, 0x09, 0xFF,
0x23, 0x03, 0x08, 0xFF, 0x3D, 0x03, 0x06, 0xFF, 0x55, 0x03, 0x08, 0xFF, 0x6F, 0x03,
0x07, 0xFF, 0x8D, 0x03, 0x07, 0xFF, 0xAE, 0x03, 0x0A, 0xFF, 0xC9, 0x03, 0x06, 0xFF,
0xF2, 0x03, 0x06, 0xFF, 0x1D, 0x04, 0x0B, 0xFF, 0x4F, 0x04, 0x08, 0xFF, 0xC0, 0x77,
0xBC, 0x01, 0x0B, 0xFF, 0xC3, 0x01, 0x0C, 0xFF, 0xCA, 0x01, 0x0B, 0xFF, 0xD0, 0x01,
0x0B, 0xFF, 0xD7, 0x01, 0x0C, 0xFF, 0xDE, 0x01, 0x0B, 0xFF, 0xE6, 0x01, 0x0B, 0xFF,
0xEE, 0x01, 0x0B, 0xFF, 0xF6, 0x01, 0x0B, 0xFF, 0xFE, 0x01, 0x0B, 0xFF, 0x0F, 0x02,
0x07, 0xFF, 0x37, 0x02, 0x06, 0xFF, 0x72, 0x02, 0x08, 0xFF, 0x89, 0x02, 0x08, 0xFF,
0x91, 0x02, 0x09, 0xFF, 0xA4, 0x02, 0x09, 0xFF, 0xB0, 0x02, 0x09, 0xFF, 0xBF, 0x02,
0x08, 0xFF, 0xD4, 0x02, 0x08, 0xFF, 0xE3, 0x02, 0x07, 0xFF, 0xF5, 0x02, 0x07, 0xFF,
0x08, 0x03, 0x09, 0xFF, 0x23, 0x03, 0x08, 0xFF, 0x3D, 0x03, 0x06, 0xFF, 0x55, 0x03,
0x08, 0xFF, 0x6F, 0x03, 0x07, 0xFF, 0x8D, 0x03, 0x07, 0xFF, 0xAE, 0x03, 0x0A, 0xFF,
0xC9, 0x03, 0x06, 0xFF, 0xF2, 0x03, 0x06, 0xFF, 0x1D, 0x04, 0x0B, 0xFF, 0x4F, 0x04,
0x08, 0xFF, 0x00, 0x00, 0x86, 0xF4, 0x07, 0x83, 0x07, 0x00, 0x01, 0x00, 0x3C, 0x58,
0x02, 0x7C, 0x09, 0x11, 0x0F, 0x2F, 0x0C, 0x37, 0x73, 0x0A, 0x00, 0x42, 0x96, 0x13,
0x85, 0x01,
];

let (robot_clock, mock) = RobotClock::mock();
// push the time by 1s because the first emulated test packet could end up in negative time.
mock.increment(std::time::Duration::new(1, 0));

let mut cap =
Capture::from_file("tests/hesai-xt32-small.pcap").expect("Failed to open pcap file");

if let Ok(packet) = cap.next_packet() {
let udp_header_size = 0x2A;
if packet.data.len() < udp_header_size + size_of::<Packet>() {
panic!("Packet too short: {}", packet.data.len());
}
let packet_data = &packet.data[udp_header_size..udp_header_size + size_of::<Packet>()];
let packet = parse_packet(packet_data).unwrap();

let rt: RefTime = (
packet.tail.utc_tov().unwrap(), // emulates a packet coming in recently
robot_clock.now(),
);
for (bid, ts) in packet.block_ts(&rt).unwrap().iter().enumerate() {
println!("Block {} tov: {}", bid, ts);
}
let udp_header_size = 0x2A;
if packet.len() < udp_header_size + size_of::<Packet>() {
panic!("Packet too short: {}", packet.len());
}
let packet_data = &packet[udp_header_size..udp_header_size + size_of::<Packet>()];
let packet = parse_packet(packet_data).unwrap();

let rt: RefTime = (
packet.tail.utc_tov().unwrap(), // emulates a packet coming in recently
robot_clock.now(),
);
for (bid, ts) in packet.block_ts(&rt).unwrap().iter().enumerate() {
println!("Block {} tov: {}", bid, ts);
}
}
}
4 changes: 3 additions & 1 deletion components/sources/cu_vlp16/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ ignored = ["cu29-log", "cu29-log-runtime", "cu29-soa-derive"] # proc macro
cu29 = { workspace = true }
cu-sensor-payloads = { workspace = true }
velodyne-lidar = { version = "0.3.0", features = ["full"] }
pcap-file = "2.0.0"

[dev-dependencies]
cu-udp-inject = { path = "../../testing/cu_udp_inject" }
26 changes: 12 additions & 14 deletions components/sources/cu_vlp16/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use velodyne_lidar::Packet;
use velodyne_lidar::{Config, Config16};
use velodyne_lidar::{DataPacket, Packet};

use cu29::clock::RobotClock;
use cu29::config::ComponentConfig;
Expand Down Expand Up @@ -61,7 +61,7 @@ impl<'cl> CuSrcTask<'cl> for Vlp16 {

fn process(&mut self, _clock: &RobotClock, new_msg: Self::Output) -> CuResult<()> {
let socket = self.socket.as_ref().unwrap();
let mut packet = [0u8; 1206];
let mut packet = [0u8; size_of::<DataPacket>()];
let (read_size, _peer_addr) = socket.recv_from(&mut packet).unwrap();
let packet = &packet[..read_size];

Expand Down Expand Up @@ -94,30 +94,28 @@ impl<'cl> CuSrcTask<'cl> for Vlp16 {
}
}

#[cfg(test)]
mod tests {
use pcap_file::pcap::PcapReader;
use std::fs::File;

use super::*;
use cu_udp_inject::PcapStreamer;

#[test]
fn vlp16_end_2_end_test() {
let clk = RobotClock::new();
let cfg = ComponentConfig::new();
let mut drv = Vlp16::new(Some(&cfg)).unwrap();
let file_in = File::open("test/VLP_16_Single.pcap").expect("Error opening file");
let mut pcap_reader = PcapReader::new(file_in).unwrap();

let mut streamer = PcapStreamer::new("test/VLP_16_Single.pcap", "127.0.0.1:2368");

drv.start(&clk).unwrap();

const PACKET_SIZE: usize = size_of::<DataPacket>();

// Read test.pcap
if let Some(pkt) = pcap_reader.next_packet() {
let pkt = pkt.unwrap();
let data = &pkt.data[0x2a..];
// send udp packet to 2368
let socket = UdpSocket::bind("0.0.0.0:2367").unwrap();
socket.send_to(data, "127.0.0.1:2368").unwrap();
// process
if streamer
.send_next::<PACKET_SIZE>()
.expect("Failed to send packet")
{
let mut msg = CuMsg::new(Some(PointCloudSoa::<10000>::default()));
drv.process(&clk, &mut msg).unwrap();
assert_eq!(-0.05115497, msg.payload().unwrap().x[0].value);
Expand Down
2 changes: 0 additions & 2 deletions components/tasks/README.md

This file was deleted.

15 changes: 15 additions & 0 deletions components/testing/cu_udp_inject/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "cu-udp-inject"
description = "A simple UDP packet injector that takes a PCAP file and sends it to a remote host"
version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
pcap = "2.2.0"
cu29-traits = { workspace = true }
Loading
Loading