Skip to content

Commit

Permalink
Add transfer_buffer_length to handle_urb
Browse files Browse the repository at this point in the history
  • Loading branch information
h7x4 committed Aug 23, 2023
1 parent 8506ede commit 2233140
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/cdc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl UsbInterfaceHandler for UsbCdcAcmHandler {
&mut self,
_interface: &UsbInterface,
ep: UsbEndpoint,
_transfer_buffer_length: u32,
_setup: SetupPacket,
req: &[u8],
) -> Result<Vec<u8>> {
Expand Down
24 changes: 14 additions & 10 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ impl UsbDevice {
&self,
ep: UsbEndpoint,
intf: Option<&UsbInterface>,
transfer_buffer_length: u32,
setup_packet: SetupPacket,
out_data: &Vec<u8>,
) -> Result<Vec<u8>> {
Expand Down Expand Up @@ -374,15 +375,14 @@ impl UsbDevice {
// only low 8 bits are valid
let intf = &self.interfaces[setup_packet.index as usize & 0xFF];
let mut handler = intf.handler.lock().unwrap();
let resp = handler.handle_urb(intf, ep, setup_packet, &out_data)?;
return Ok(resp);
handler.handle_urb(intf, ep, transfer_buffer_length, setup_packet, out_data)
}
_ if setup_packet.request_type & 0xF == 0 && self.device_handler.is_some() => {
// to device
// see https://www.beyondlogic.org/usbnutshell/usb6.shtml
let lock = self.device_handler.as_ref().unwrap();
let mut handler = lock.lock().unwrap();
return Ok(handler.handle_urb(setup_packet, &out_data)?);
handler.handle_urb(transfer_buffer_length, setup_packet, out_data)
}
_ => unimplemented!("control in"),
}
Expand Down Expand Up @@ -411,15 +411,14 @@ impl UsbDevice {
// only low 8 bits are valid
let intf = &self.interfaces[setup_packet.index as usize & 0xFF];
let mut handler = intf.handler.lock().unwrap();
let resp = handler.handle_urb(intf, ep, setup_packet, &out_data)?;
return Ok(resp);
handler.handle_urb(intf, ep, transfer_buffer_length, setup_packet, out_data)
}
_ if setup_packet.request_type & 0xF == 0 && self.device_handler.is_some() => {
// to device
// see https://www.beyondlogic.org/usbnutshell/usb6.shtml
let lock = self.device_handler.as_ref().unwrap();
let mut handler = lock.lock().unwrap();
return Ok(handler.handle_urb(setup_packet, &out_data)?);
handler.handle_urb(transfer_buffer_length, setup_packet, out_data)
}
_ => unimplemented!("control out"),
}
Expand All @@ -428,8 +427,7 @@ impl UsbDevice {
// others
let intf = intf.unwrap();
let mut handler = intf.handler.lock().unwrap();
let resp = handler.handle_urb(intf, ep, setup_packet, &out_data)?;
return Ok(resp);
handler.handle_urb(intf, ep, transfer_buffer_length, setup_packet, out_data)
}
_ => unimplemented!("transfer to {:?}", ep),
}
Expand All @@ -440,8 +438,14 @@ impl UsbDevice {
pub trait UsbDeviceHandler {
/// Handle a URB(USB Request Block) targeting at this device
///
/// When the lower 4 bits of bmRequestType is zero and the URB is not handled by the library, this function is called
fn handle_urb(&mut self, setup: SetupPacket, req: &[u8]) -> Result<Vec<u8>>;
/// When the lower 4 bits of `bmRequestType` is zero and the URB is not handled by the library, this function is called.
/// The resulting data should not exceed `transfer_buffer_length`
fn handle_urb(
&mut self,
transfer_buffer_length: u32,
setup: SetupPacket,
req: &[u8],
) -> Result<Vec<u8>>;

/// Helper to downcast to actual struct
///
Expand Down
1 change: 1 addition & 0 deletions src/hid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl UsbInterfaceHandler for UsbHidKeyboardHandler {
&mut self,
_interface: &UsbInterface,
ep: UsbEndpoint,
_transfer_buffer_length: u32,
setup: SetupPacket,
_req: &[u8],
) -> Result<Vec<u8>> {
Expand Down
12 changes: 9 additions & 3 deletions src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ impl UsbInterfaceHandler for UsbHostInterfaceHandler {
&mut self,
_interface: &UsbInterface,
ep: UsbEndpoint,
transfer_buffer_length: u32,
setup: SetupPacket,
req: &[u8],
) -> Result<Vec<u8>> {
debug!(
"To host device: ep={:?} setup={:?} req={:?}",
ep, setup, req
);
let mut buffer = vec![0u8; ep.max_packet_size as usize];
let mut buffer = vec![0u8; transfer_buffer_length as usize];
let timeout = std::time::Duration::new(1, 0);
let handle = self.handle.lock().unwrap();
if ep.attributes == EndpointAttributes::Control as u8 {
Expand Down Expand Up @@ -104,9 +105,14 @@ impl UsbHostDeviceHandler {
}

impl UsbDeviceHandler for UsbHostDeviceHandler {
fn handle_urb(&mut self, setup: SetupPacket, req: &[u8]) -> Result<Vec<u8>> {
fn handle_urb(
&mut self,
transfer_buffer_length: u32,
setup: SetupPacket,
req: &[u8],
) -> Result<Vec<u8>> {
debug!("To host device: setup={:?} req={:?}", setup, req);
let mut buffer = [0u8; 1024];
let mut buffer = vec![0u8; transfer_buffer_length as usize];
let timeout = std::time::Duration::new(1, 0);
let handle = self.handle.lock().unwrap();
// control
Expand Down
4 changes: 3 additions & 1 deletion src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ pub trait UsbInterfaceHandler {

/// Handle a URB(USB Request Block) targeting at this interface
///
/// Can be one of: control transfer to ep0 or other types of transfer to its endpoint
/// Can be one of: control transfer to ep0 or other types of transfer to its endpoint.
/// The resulting data should not exceed `transfer_buffer_length`.
fn handle_urb(
&mut self,
interface: &UsbInterface,
ep: UsbEndpoint,
transfer_buffer_length: u32,
setup: SetupPacket,
req: &[u8],
) -> Result<Vec<u8>>;
Expand Down
10 changes: 8 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,13 @@ async fn handler<T: AsyncReadExt + AsyncWriteExt + Unpin>(
trace!("->Setup {:02x?}", setup);
trace!("->Request {:02x?}", out_data);
let resp = device
.handle_urb(usb_ep, intf, SetupPacket::parse(&setup), &out_data)
.handle_urb(
usb_ep,
intf,
transfer_buffer_length,
SetupPacket::parse(&setup),
&out_data,
)
.await?;

if out {
Expand All @@ -315,7 +321,7 @@ async fn handler<T: AsyncReadExt + AsyncWriteExt + Unpin>(
// In the out endpoint case, the actual_length field should be
// same as the data length received in the original URB transaction.
// No data bytes are sent
transfer_buffer_length as u32
transfer_buffer_length
} else {
resp.len() as u32
};
Expand Down

0 comments on commit 2233140

Please sign in to comment.