Skip to content

Commit eadbbc9

Browse files
committed
Add tests for isochronous endpoint descriptors
1 parent f4582c0 commit eadbbc9

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/test_class.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct TestClass<'a, B: UsbBus> {
3232
ep_bulk_out: EndpointOut<'a, B>,
3333
ep_interrupt_in: EndpointIn<'a, B>,
3434
ep_interrupt_out: EndpointOut<'a, B>,
35+
ep_iso_in: EndpointIn<'a, B>,
3536
control_buf: [u8; sizes::BUFFER],
3637
bulk_buf: [u8; sizes::BUFFER],
3738
interrupt_buf: [u8; sizes::BUFFER],
@@ -72,6 +73,12 @@ impl<B: UsbBus> TestClass<'_, B> {
7273
ep_bulk_out: alloc.bulk(sizes::BULK_ENDPOINT),
7374
ep_interrupt_in: alloc.interrupt(sizes::INTERRUPT_ENDPOINT, 1),
7475
ep_interrupt_out: alloc.interrupt(sizes::INTERRUPT_ENDPOINT, 1),
76+
ep_iso_in: alloc.isochronous(
77+
IsochronousSynchronizationType::Asynchronous,
78+
IsochronousUsageType::ImplicitFeedbackData,
79+
500, // These last two args are arbitrary in this usage, they
80+
1, // let the host know how much bandwidth to reserve.
81+
),
7582
control_buf: [0; sizes::BUFFER],
7683
bulk_buf: [0; sizes::BUFFER],
7784
interrupt_buf: [0; sizes::BUFFER],
@@ -218,7 +225,7 @@ impl<B: UsbBus> UsbClass<B> for TestClass<'_, B> {
218225
writer.endpoint(&self.ep_interrupt_in)?;
219226
writer.endpoint(&self.ep_interrupt_out)?;
220227
writer.interface_alt(self.iface, 1, 0xff, 0x01, 0x00, Some(self.interface_string))?;
221-
228+
writer.endpoint(&self.ep_iso_in)?;
222229
Ok(())
223230
}
224231

tests/test_class_host/tests.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::device::*;
22
use rand::prelude::*;
3-
use rusb::{request_type, Direction, Recipient, RequestType};
3+
use rusb::{request_type, Direction, Recipient, RequestType, TransferType};
44
use std::cmp::max;
55
use std::fmt::Write;
66
use std::time::{Duration, Instant};
@@ -163,6 +163,40 @@ fn interface_descriptor(dev, _out) {
163163
test_class::INTERFACE_STRING);
164164
}
165165

166+
fn iso_endpoint_descriptors(dev, _out) {
167+
// Tests that an isochronous endpoint descriptor is present in the first
168+
// alternate setting, but not in the default setting.
169+
let iface = dev.config_descriptor
170+
.interfaces()
171+
.find(|i| i.number() == 0)
172+
.expect("interface not found");
173+
174+
let mut iso_ep_count = 0;
175+
for iface_descriptor in iface.descriptors() {
176+
if iface_descriptor.setting_number() == 0 {
177+
// Default setting - no isochronous endpoints allowed. Per USB 2.0
178+
// spec rev 2.0, 5.6.3 Isochronous Transfer Packet Size Constraints:
179+
//
180+
// All device default interface settings must not include any
181+
// isochronous endpoints with non-zero data payload sizes (specified
182+
// via wMaxPacketSize in the endpoint descriptor)
183+
let issue = iface_descriptor
184+
.endpoint_descriptors()
185+
.find(|ep| ep.transfer_type() == TransferType::Isochronous
186+
&& ep.max_packet_size() != 0);
187+
if let Some(ep) = issue {
188+
panic!("Endpoint {} is isochronous and in the default setting",
189+
ep.number());
190+
}
191+
} else {
192+
iso_ep_count += iface_descriptor.endpoint_descriptors()
193+
.filter(|ep| ep.transfer_type() == TransferType::Isochronous)
194+
.count();
195+
}
196+
}
197+
assert!(iso_ep_count > 0, "At least one isochronous endpoint is expected");
198+
}
199+
166200
fn bulk_loopback(dev, _out) {
167201
let mut lens = vec![0, 1, 2, 32, 63, 64, 65, 127, 128, 129];
168202
if dev.is_high_speed() {

0 commit comments

Comments
 (0)