1
0
Fork 0
mirror of https://github.com/G2-Games/cross-usb.git synced 2025-05-02 19:32:54 -05:00

Implemented bulk transfers, cleaned up code, added some docs

This commit is contained in:
G2-Games 2024-01-31 12:05:39 -06:00
parent 8b624b0136
commit 1a350800cf
5 changed files with 58 additions and 13 deletions

View file

@ -2,6 +2,17 @@
name = "cross_usb"
version = "0.1.0"
authors = ["G2-Games <ke0bhogsg@gmail.com>"]
repository = "https://github.com/G2-Games/cross-usb"
documentation = "https://docs.rs/cross_usb"
description = """
A a Rust USB library which works seamlessly across both native and WASM targets
"""
keywords = ["usb", "wasm", "web-usb"]
categories = ["wasm", "web-programming", "hardware-support"]
readme = "README.md"
license = "AGPL-3.0"
edition = "2021"
[lib]
@ -28,6 +39,7 @@ features = [
"UsbControlTransferParameters",
"UsbDeviceRequestOptions",
"UsbInTransferResult",
"UsbOutTransferResult",
"Storage"
]

View file

@ -12,7 +12,6 @@ pub struct UsbInterface {
interface: nusb::Interface,
}
/// Gets a single device from the VendorID and ProductID
pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, Box<dyn Error>> {
let devices = nusb::list_devices().unwrap();
@ -100,8 +99,8 @@ impl<'a> Interface<'a> for UsbInterface {
Ok(self.interface.bulk_in(endpoint, request_buffer).await.into_result()?)
}
async fn bulk_out(&self, endpoint: u8, data: Vec<u8>) -> Result<usize, Box<dyn Error>> {
match self.interface.bulk_out(endpoint, data).await.into_result() {
async fn bulk_out(&self, endpoint: u8, data: &[u8]) -> Result<usize, Box<dyn Error>> {
match self.interface.bulk_out(endpoint, data.to_vec()).await.into_result() {
Ok(len) => Ok(len.actual_length()),
Err(e) => Err(e.into())
}

View file

@ -10,6 +10,7 @@ use web_sys::{
UsbInterface as WasmUsbInterface,
UsbControlTransferParameters,
UsbInTransferResult,
UsbOutTransferResult,
UsbRecipient,
UsbRequestType,
UsbDeviceRequestOptions,
@ -30,7 +31,6 @@ pub struct UsbInterface {
device: WasmUsbDevice,
}
/// Gets a single device from the VendorID and ProductID
#[wasm_bindgen]
pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, js_sys::Error> {
let window = web_sys::window().unwrap();
@ -136,9 +136,8 @@ impl<'a> Interface<'a> for UsbInterface {
let length = data.length;
let params: UsbControlTransferParameters = data.into();
let result = JsFuture::from(Promise::resolve(
&self.device.control_transfer_in(&params, length)
)).await;
let promise = Promise::resolve(&self.device.control_transfer_in(&params, length));
let result = JsFuture::from(promise).await;
let transfer_result: UsbInTransferResult = match result {
Ok(res) => res.into(),
@ -169,12 +168,40 @@ impl<'a> Interface<'a> for UsbInterface {
}
}
async fn bulk_in(&self, _endpoint: u8, _length: usize) -> Result<Vec<u8>, Box<dyn Error>> {
todo!()
async fn bulk_in(&self, endpoint: u8, length: usize) -> Result<Vec<u8>, Box<dyn Error>> {
let promise = Promise::resolve(&self.device.transfer_in(endpoint, length as u32));
let result = JsFuture::from(promise).await;
let transfer_result: UsbInTransferResult = match result {
Ok(res) => res.into(),
Err(err) => return Err(format!("Error {:?}", err).into()),
};
let data = match transfer_result.data() {
Some(res) => res.buffer(),
None => return Err("No data returned".into()),
};
let array = Uint8Array::new(&data);
Ok(array.to_vec())
}
async fn bulk_out(&self, _endpoint: u8, _data: Vec<u8>) -> Result<usize, Box<dyn Error>> {
todo!()
async fn bulk_out(&self, endpoint: u8, data: &[u8]) -> Result<usize, Box<dyn Error>> {
let array = Uint8Array::from(data);
let array_obj = Object::try_from(&array).unwrap();
let promise = Promise::resolve(&self.device.transfer_out_with_buffer_source(endpoint, array_obj));
let result = JsFuture::from(promise).await;
let transfer_result: UsbOutTransferResult = match result {
Ok(res) => res.into(),
Err(err) => return Err(format!("Error {:?}", err).into()),
};
Ok(transfer_result.bytes_written() as usize)
}
}

View file

@ -7,3 +7,7 @@ pub mod context;
#[cfg(target_family = "wasm")]
#[path = "./backend/wasm.rs"]
pub mod context;
/// Gets a single device from the VendorID and ProductID
#[doc(inline)]
pub use crate::context::get_device;

View file

@ -37,16 +37,19 @@ pub trait Device {
/// A specific interface of a USB device
pub trait Interface<'a> {
/// A USB control in transfer (device to host)
/// Returns a [Result] with the bytes in a `Vec<u8>`
async fn control_in(&self, data: ControlIn) -> Result<Vec<u8>, Box<dyn Error>>;
/// A USB control out transfer (host to device)
async fn control_out(&self, data: ControlOut<'a>) -> Result<(), Box<dyn Error>>;
/// A USB bulk in transfer (device to host)
/// Returns a [Result] with the bytes in a `Vec<u8>`
async fn bulk_in(&self, endpoint: u8, length: usize) -> Result<Vec<u8>, Box<dyn Error>>;
/// A USB bulk out transfer (host to device)
async fn bulk_out(&self, endpoint: u8, data: Vec<u8>) -> Result<usize, Box<dyn Error>>;
/// A USB bulk out transfer (host to device).
/// Returns a [Result] with the number of bytes transferred
async fn bulk_out(&self, endpoint: u8, data: &[u8]) -> Result<usize, Box<dyn Error>>;
async fn interrupt_in(&self, _endpoint: u8, _buf: Vec<u8>) {
unimplemented!()