Skip to content

Commit

Permalink
Add test verifying SOF packets have the expected timestamp intervals.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinling committed Jun 25, 2024
1 parent 6594eec commit eb214dc
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ pub struct Transaction {
start_pid: PID,
end_pid: PID,
split: Option<(SplitFields, PID)>,
packet_id_range: Range<PacketId>,
pub packet_id_range: Range<PacketId>,
data_packet_id: Option<PacketId>,
payload_byte_range: Option<Range<Id<u8>>>,
}
Expand Down Expand Up @@ -881,7 +881,7 @@ impl CaptureReader {
Ok(PID::from(self.packet_data.get(offset)?))
}

fn transaction(&mut self, id: TransactionId)
pub fn transaction(&mut self, id: TransactionId)
-> Result<Transaction, Error>
{
let packet_id_range = self.transaction_index.target_range(
Expand Down
66 changes: 59 additions & 7 deletions src/test_cynthion.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
use crate::backend::cynthion::{CynthionDevice, CynthionUsability, Speed};
use crate::capture::{create_capture, CaptureReader, DeviceId, EndpointId, EndpointTransferId};
use crate::capture::{
create_capture,
CaptureReader,
DeviceId,
EndpointId,
EndpointTransferId,
PacketId,
};
use crate::decoder::Decoder;

use anyhow::{Context, Error};
Expand All @@ -10,16 +17,21 @@ use std::thread::sleep;
use std::time::Duration;

pub fn run_test() {
for (speed, ep_addr, length) in [
(Speed::High, 0x81, 4096),
(Speed::Full, 0x82, 512),
(Speed::Low, 0x83, 64)]
for (speed, ep_addr, length, sof) in [
(Speed::High, 0x81, 4096, Some((124500, 125500, 500))),
(Speed::Full, 0x82, 512, Some((995000, 1005000, 50))),
(Speed::Low, 0x83, 64, None)]
{
test(speed, ep_addr, length).unwrap();
test(speed, ep_addr, length, sof).unwrap();
}
}

fn test(speed: Speed, ep_addr: u8, length: usize) -> Result<(), Error> {
fn test(speed: Speed,
ep_addr: u8,
length: usize,
sof: Option<(u64, u64, u64)>)
-> Result<(), Error>
{
let desc = speed.description();
println!("\nTesting at {desc}:\n");

Expand Down Expand Up @@ -100,6 +112,46 @@ fn test(speed: Speed, ep_addr: u8, length: usize) -> Result<(), Error> {
assert_eq!(bytes_captured, completion.data,
"Captured data did not match received data");

if let Some((min_interval, max_interval, min_count)) = sof {
println!("Checking SOF timestamp intervals");
// Check SOF timestamps have the expected spacing.
// SOF packets are assigned to endpoint ID 1.
// We're looking for the first and only transfer on the endpoint.
let endpoint_id = EndpointId::from(1);
let ep_transfer_id = EndpointTransferId::from(0);
let ep_traf = reader.endpoint_traffic(endpoint_id)?;
let ep_transaction_ids = ep_traf.transfer_index
.target_range(ep_transfer_id, ep_traf.transaction_ids.len())?;
let mut sof_count = 0;
let mut last = None;
for transaction_id in ep_traf.transaction_ids
.get_range(&ep_transaction_ids)?
{
let range = reader.transaction_index
.target_range(transaction_id, reader.packet_index.len())?;
for id in range.start.value..range.end.value {
let packet_id = PacketId::from(id);
let timestamp = reader.packet_times.get(packet_id)?;
if let Some(prev) = last {
let interval = timestamp - prev;
if !(interval > min_interval && interval < max_interval) {
if interval > 10000000 {
// More than 10ms gap, assume host stopped sending.
continue
} else {
panic!("SOF interval of {}ns is out of range",
interval);
}
}
}
sof_count += 1;
last = Some(timestamp);
}
}
println!("Found {} SOF packets with expected interval range", sof_count);
assert!(sof_count > min_count, "Not enough SOF packets captured");
}

Ok(())
}

Expand Down

0 comments on commit eb214dc

Please sign in to comment.