Add initial nusb support for #54
This commit is contained in:
parent
af17fc2243
commit
9c1efa1dd3
3 changed files with 148 additions and 12 deletions
|
|
@ -16,6 +16,7 @@ num-traits = "0.2.15"
|
|||
num-derive = "0.3.3"
|
||||
rusb = "0.9.3"
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
nusb = "0.1.10"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.22.0", features = ["full"] }
|
||||
|
|
|
|||
149
src/host.rs
149
src/host.rs
|
|
@ -1,19 +1,19 @@
|
|||
//! Host USB
|
||||
use super::*;
|
||||
|
||||
/// A handler to pass requests to a USB device of the host
|
||||
/// A handler to pass requests to a rusb USB device of the host
|
||||
#[derive(Clone)]
|
||||
pub struct UsbHostInterfaceHandler {
|
||||
pub struct RusbUsbHostInterfaceHandler {
|
||||
handle: Arc<Mutex<DeviceHandle<GlobalContext>>>,
|
||||
}
|
||||
|
||||
impl UsbHostInterfaceHandler {
|
||||
impl RusbUsbHostInterfaceHandler {
|
||||
pub fn new(handle: Arc<Mutex<DeviceHandle<GlobalContext>>>) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl UsbInterfaceHandler for UsbHostInterfaceHandler {
|
||||
impl UsbInterfaceHandler for RusbUsbHostInterfaceHandler {
|
||||
fn handle_urb(
|
||||
&mut self,
|
||||
_interface: &UsbInterface,
|
||||
|
|
@ -94,17 +94,17 @@ impl UsbInterfaceHandler for UsbHostInterfaceHandler {
|
|||
|
||||
/// A handler to pass requests to a USB device of the host
|
||||
#[derive(Clone)]
|
||||
pub struct UsbHostDeviceHandler {
|
||||
pub struct RusbUsbHostDeviceHandler {
|
||||
handle: Arc<Mutex<DeviceHandle<GlobalContext>>>,
|
||||
}
|
||||
|
||||
impl UsbHostDeviceHandler {
|
||||
impl RusbUsbHostDeviceHandler {
|
||||
pub fn new(handle: Arc<Mutex<DeviceHandle<GlobalContext>>>) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl UsbDeviceHandler for UsbHostDeviceHandler {
|
||||
impl UsbDeviceHandler for RusbUsbHostDeviceHandler {
|
||||
fn handle_urb(
|
||||
&mut self,
|
||||
transfer_buffer_length: u32,
|
||||
|
|
@ -148,3 +148,138 @@ impl UsbDeviceHandler for UsbHostDeviceHandler {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A handler to pass requests to a rusb USB device of the host
|
||||
#[derive(Clone)]
|
||||
pub struct NusbUsbHostInterfaceHandler {
|
||||
handle: Arc<Mutex<nusb::Interface>>,
|
||||
}
|
||||
|
||||
impl NusbUsbHostInterfaceHandler {
|
||||
pub fn new(handle: Arc<Mutex<nusb::Interface>>) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl UsbInterfaceHandler for NusbUsbHostInterfaceHandler {
|
||||
fn handle_urb(
|
||||
&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; transfer_buffer_length as usize];
|
||||
let timeout = std::time::Duration::new(1, 0);
|
||||
let handle = self.handle.lock().unwrap();
|
||||
let control = nusb::transfer::Control {
|
||||
control_type: match (setup.request_type >> 5) & 0b11 {
|
||||
0 => nusb::transfer::ControlType::Standard,
|
||||
1 => nusb::transfer::ControlType::Class,
|
||||
2 => nusb::transfer::ControlType::Vendor,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
recipient: match setup.request_type & 0b11111 {
|
||||
0 => nusb::transfer::Recipient::Device,
|
||||
1 => nusb::transfer::Recipient::Interface,
|
||||
2 => nusb::transfer::Recipient::Endpoint,
|
||||
3 => nusb::transfer::Recipient::Other,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
request: setup.request,
|
||||
value: setup.value,
|
||||
index: setup.index,
|
||||
};
|
||||
if ep.attributes == EndpointAttributes::Control as u8 {
|
||||
// control
|
||||
if let Direction::In = ep.direction() {
|
||||
// control in
|
||||
if let Ok(len) = handle.control_in_blocking(control, &mut buffer, timeout) {
|
||||
return Ok(Vec::from(&buffer[..len]));
|
||||
}
|
||||
} else {
|
||||
// control out
|
||||
handle.control_out_blocking(control, req, timeout).ok();
|
||||
}
|
||||
} else if ep.attributes == EndpointAttributes::Interrupt as u8 {
|
||||
// interrupt
|
||||
todo!("Missing blocking api for interrupt transfer in nusb")
|
||||
} else if ep.attributes == EndpointAttributes::Bulk as u8 {
|
||||
// bulk
|
||||
todo!("Missing blocking api for bulk transfer in nusb")
|
||||
}
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn get_class_specific_descriptor(&self) -> Vec<u8> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn as_any(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A handler to pass requests to a USB device of the host
|
||||
#[derive(Clone)]
|
||||
pub struct NusbUsbHostDeviceHandler {
|
||||
handle: Arc<Mutex<nusb::Device>>,
|
||||
}
|
||||
|
||||
impl NusbUsbHostDeviceHandler {
|
||||
pub fn new(handle: Arc<Mutex<nusb::Device>>) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl UsbDeviceHandler for NusbUsbHostDeviceHandler {
|
||||
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 = vec![0u8; transfer_buffer_length as usize];
|
||||
let timeout = std::time::Duration::new(1, 0);
|
||||
let handle = self.handle.lock().unwrap();
|
||||
let control = nusb::transfer::Control {
|
||||
control_type: match (setup.request_type >> 5) & 0b11 {
|
||||
0 => nusb::transfer::ControlType::Standard,
|
||||
1 => nusb::transfer::ControlType::Class,
|
||||
2 => nusb::transfer::ControlType::Vendor,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
recipient: match setup.request_type & 0b11111 {
|
||||
0 => nusb::transfer::Recipient::Device,
|
||||
1 => nusb::transfer::Recipient::Interface,
|
||||
2 => nusb::transfer::Recipient::Endpoint,
|
||||
3 => nusb::transfer::Recipient::Other,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
request: setup.request,
|
||||
value: setup.value,
|
||||
index: setup.index,
|
||||
};
|
||||
// control
|
||||
if setup.request_type & 0x80 == 0 {
|
||||
// control out
|
||||
handle.control_out_blocking(control, req, timeout).ok();
|
||||
} else {
|
||||
// control in
|
||||
if let Ok(len) = handle.control_in_blocking(control, &mut buffer, timeout) {
|
||||
return Ok(Vec::from(&buffer[..len]));
|
||||
}
|
||||
}
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn as_any(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/lib.rs
10
src/lib.rs
|
|
@ -54,7 +54,7 @@ impl UsbIpServer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a [UsbIpServer] with Vec<[rusb::DeviceHandle]>
|
||||
/// Create a [UsbIpServer] with Vec<[rusb::DeviceHandle]> for sharing host devices
|
||||
pub fn with_device_handles(device_handles: Vec<DeviceHandle<GlobalContext>>) -> Vec<UsbDevice> {
|
||||
let mut devices = vec![];
|
||||
for open_device in device_handles {
|
||||
|
|
@ -106,7 +106,7 @@ impl UsbIpServer {
|
|||
});
|
||||
}
|
||||
|
||||
let handler = Arc::new(Mutex::new(Box::new(UsbHostInterfaceHandler::new(
|
||||
let handler = Arc::new(Mutex::new(Box::new(RusbUsbHostInterfaceHandler::new(
|
||||
handle.clone(),
|
||||
))
|
||||
as Box<dyn UsbInterfaceHandler + Send>));
|
||||
|
|
@ -157,9 +157,9 @@ impl UsbIpServer {
|
|||
interval: 0,
|
||||
},
|
||||
interfaces,
|
||||
device_handler: Some(Arc::new(Mutex::new(Box::new(UsbHostDeviceHandler::new(
|
||||
handle.clone(),
|
||||
))))),
|
||||
device_handler: Some(Arc::new(Mutex::new(Box::new(
|
||||
RusbUsbHostDeviceHandler::new(handle.clone()),
|
||||
)))),
|
||||
usb_version: desc.usb_version().into(),
|
||||
..UsbDevice::default()
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue