Fixed some problems with wasm

This commit is contained in:
G2-Games 2024-01-30 18:06:44 -06:00
parent 3bad540481
commit db9605fbb7
4 changed files with 72 additions and 46 deletions

View file

@ -1,5 +1,5 @@
[package] [package]
name = "cross-usb" name = "cross_usb"
version = "0.1.0" version = "0.1.0"
authors = ["G2-Games <ke0bhogsg@gmail.com>"] authors = ["G2-Games <ke0bhogsg@gmail.com>"]
edition = "2021" edition = "2021"
@ -25,6 +25,7 @@ features = [
"UsbRequestType", "UsbRequestType",
"UsbControlTransferParameters", "UsbControlTransferParameters",
"UsbDeviceRequestOptions", "UsbDeviceRequestOptions",
"UsbInTransferResult",
"Storage" "Storage"
] ]
@ -34,5 +35,8 @@ nusb = "0.1.4"
[profile.release] [profile.release]
opt-level = "s" opt-level = "s"
[dependencies]
thiserror = "1.0.56"
[package.metadata.wasm-pack.profile.dev.wasm-bindgen] [package.metadata.wasm-pack.profile.dev.wasm-bindgen]
dwarf-debug-info = true dwarf-debug-info = true

View file

@ -4,6 +4,7 @@ use nusb;
use crate::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient}; use crate::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient};
pub struct UsbDevice { pub struct UsbDevice {
device_info: nusb::DeviceInfo,
device: nusb::Device, device: nusb::Device,
} }
@ -30,7 +31,10 @@ pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, Bo
let device = device_info.open()?; let device = device_info.open()?;
Ok(UsbDevice { device }) Ok(UsbDevice {
device_info,
device
})
} }
impl Device for UsbDevice { impl Device for UsbDevice {
@ -52,6 +56,14 @@ impl Device for UsbDevice {
Err(e) => Err(e.into()) Err(e) => Err(e.into())
} }
} }
async fn vendor_id(&self) -> u16 {
self.device_info.vendor_id()
}
async fn product_id(&self) -> u16 {
self.device_info.product_id()
}
} }
impl<'a> Interface<'a> for UsbInterface { impl<'a> Interface<'a> for UsbInterface {
@ -66,16 +78,15 @@ impl<'a> Interface<'a> for UsbInterface {
} }
} }
async fn bulk_in(&self, endpoint: u8, buf: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> { async fn bulk_in(&self, endpoint: u8, length: usize) -> Result<Vec<u8>, Box<dyn Error>> {
let buf_len = buf.len(); let request_buffer = nusb::transfer::RequestBuffer::new(length);
let request_buffer = nusb::transfer::RequestBuffer::reuse(buf, buf_len);
Ok(self.interface.bulk_in(endpoint, request_buffer).await.into_result()?) Ok(self.interface.bulk_in(endpoint, request_buffer).await.into_result()?)
} }
async fn bulk_out(&self, endpoint: u8, buf: Vec<u8>) -> Result<(), Box<dyn Error>> { async fn bulk_out(&self, endpoint: u8, data: Vec<u8>) -> Result<usize, Box<dyn Error>> {
match self.interface.bulk_out(endpoint, buf).await.into_result() { match self.interface.bulk_out(endpoint, data).await.into_result() {
Ok(_) => Ok(()), Ok(len) => Ok(len.actual_length()),
Err(e) => Err(e.into()) Err(e) => Err(e.into())
} }
} }

View file

@ -9,6 +9,7 @@ use web_sys::{
UsbDevice as WasmUsbDevice, UsbDevice as WasmUsbDevice,
UsbInterface as WasmUsbInterface, UsbInterface as WasmUsbInterface,
UsbControlTransferParameters, UsbControlTransferParameters,
UsbInTransferResult,
UsbRecipient, UsbRecipient,
UsbRequestType, UsbRequestType,
UsbDeviceRequestOptions, UsbDeviceRequestOptions,
@ -59,16 +60,14 @@ pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, js
let device_promise = JsFuture::from(Promise::resolve(&usb.request_device(&filters2))).await; let device_promise = JsFuture::from(Promise::resolve(&usb.request_device(&filters2))).await;
let device: WasmUsbDevice = match device_promise { let device: WasmUsbDevice = match device_promise {
Ok(res) => res.into(), Ok(dev) => dev.into(),
Err(err) => { Err(err) => {
console::log_1(&err.clone().into()); console::log_1(&err.clone());
return Err(err.into()) return Err(err.into())
}, },
}; };
let _open_promise = JsFuture::from(Promise::resolve(&device.open())); let _open_promise = JsFuture::from(Promise::resolve(&device.open())).await?;
console::log_1(&"got device".into());
Ok(UsbDevice { Ok(UsbDevice {
device device
@ -80,10 +79,17 @@ impl Device for UsbDevice {
type UsbInterface = UsbInterface; type UsbInterface = UsbInterface;
async fn open_interface(&self, number: u8) -> Result<UsbInterface, Box<dyn Error>> { async fn open_interface(&self, number: u8) -> Result<UsbInterface, Box<dyn Error>> {
let dev_promise = JsFuture::from(Promise::resolve(&self.device.claim_interface(number))); let dev_promise = JsFuture::from(Promise::resolve(&self.device.claim_interface(number))).await;
// Wait for the interface to be claimed // Wait for the interface to be claimed
let result = dev_promise; let device: WasmUsbDevice = match dev_promise {
Ok(dev) => dev.into(),
Err(err) => {
console::log_1(&err.clone());
return Err(format!("{:?}", err).into())
},
};
//let interface: WasmUsbInterface = dev_promise.await.unwrap().into();
Ok(UsbInterface { Ok(UsbInterface {
device: self.device.clone() device: self.device.clone()
@ -97,55 +103,60 @@ impl Device for UsbDevice {
match result { match result {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(_) => { Err(_) => Err("cancelled".into()),
console::log_1(&"Cancelled".into());
return Err("cancelled".into())
},
} }
} }
async fn vendor_id(&self) -> u16 {
self.device.vendor_id()
}
async fn product_id(&self) -> u16 {
self.device.product_id()
}
} }
impl<'a> Interface<'a> for UsbInterface { impl<'a> Interface<'a> for UsbInterface {
async fn control_in(&self, data: crate::usb::ControlIn) -> Result<Vec<u8>, Box<dyn Error>> { async fn control_in(&self, data: crate::usb::ControlIn) -> Result<Vec<u8>, Box<dyn Error>> {
let length = data.length; let length = data.length;
let params = data.into(); let params: UsbControlTransferParameters = data.into();
let promise = Promise::resolve(&self.device.control_transfer_in(&params, length)); let promise = Promise::resolve(&self.device.control_transfer_in(&params, length));
let mut result = JsFuture::from(promise).await; let result = JsFuture::from(promise).await;
let data = match result { let transfer_result: UsbInTransferResult = match result {
Ok(res) => res.into(), Ok(res) => res.into(),
Err(_) => { Err(err) => return Err(format!("Error {:?}", err).into()),
console::log_1(&"Cancelled".into());
return Err("cancelled".into())
},
}; };
let unitarray = Uint8Array::new(&data); let data = match transfer_result.data() {
Some(res) => res.buffer(),
None => return Err("No data returned".into()),
};
Ok(unitarray.to_vec()) let array = Uint8Array::new(&data);
Ok(array.to_vec())
} }
async fn control_out(&self, data: crate::usb::ControlOut<'a>) -> Result<(), Box<dyn Error>> { async fn control_out(&self, data: crate::usb::ControlOut<'a>) -> Result<(), Box<dyn Error>> {
let params = data.into(); let params = data.into();
let promise = Promise::resolve(&self.device.control_transfer_out(&params)); let promise = Promise::resolve(&self.device.control_transfer_out(&params));
let mut result = JsFuture::from(promise).await; let result = JsFuture::from(promise).await;
match result { match result {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(err) => { Err(err) => Err(format!("{:?}", err).into()),
console::log_1(&"Cancelled".into());
Err(format!("{:?}", err).into())
},
} }
} }
async fn bulk_in(&self, _endpoint: u8, _buf: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> { async fn bulk_in(&self, _endpoint: u8, _length: usize) -> Result<Vec<u8>, Box<dyn Error>> {
todo!() todo!()
} }
async fn bulk_out(&self, _endpoint: u8, _buf: Vec<u8>) -> Result<(), Box<dyn Error>> { async fn bulk_out(&self, _endpoint: u8, _data: Vec<u8>) -> Result<usize, Box<dyn Error>> {
todo!() todo!()
} }
} }
@ -155,7 +166,7 @@ impl From<ControlIn> for UsbControlTransferParameters {
UsbControlTransferParameters::new( UsbControlTransferParameters::new(
value.index, value.index,
value.recipient.into(), value.recipient.into(),
value.request.into(), value.request,
value.control_type.into(), value.control_type.into(),
value.value value.value
) )
@ -167,7 +178,7 @@ impl From<ControlOut<'_>> for UsbControlTransferParameters {
UsbControlTransferParameters::new( UsbControlTransferParameters::new(
value.index, value.index,
value.recipient.into(), value.recipient.into(),
value.request.into(), value.request,
value.control_type.into(), value.control_type.into(),
value.value value.value
) )

View file

@ -1,7 +1,11 @@
#![cfg_attr(debug_assertions, allow(async_fn_in_trait))] #![cfg_attr(debug_assertions, allow(async_fn_in_trait))]
use std::error::Error; use std::error::Error;
use crate::context::UsbInterface; use crate::context::UsbInterface;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum UsbError {
}
/// A unique USB device /// A unique USB device
pub trait Device { pub trait Device {
@ -10,14 +14,10 @@ pub trait Device {
async fn open_interface(&self, number: u8) -> Result<UsbInterface, Box<dyn Error>>; async fn open_interface(&self, number: u8) -> Result<UsbInterface, Box<dyn Error>>;
async fn reset(&self) -> Result<(), Box<dyn Error>>; async fn reset(&self) -> Result<(), Box<dyn Error>>;
async fn product_id(&self) -> u16;
async fn vendor_id(&self) -> u16;
//TODO: Implement these placeholders //TODO: Implement these placeholders
async fn product_id(&self) -> u16 {
0x00
}
async fn vendor_id(&self) -> u16 {
0x00
}
async fn class(&self) -> u16 { async fn class(&self) -> u16 {
0x00 0x00
} }
@ -37,8 +37,8 @@ pub trait Interface<'a> {
async fn control_in(&self, data: ControlIn) -> Result<Vec<u8>, Box<dyn Error>>; async fn control_in(&self, data: ControlIn) -> Result<Vec<u8>, Box<dyn Error>>;
async fn control_out(&self, data: ControlOut<'a>) -> Result<(), Box<dyn Error>>; async fn control_out(&self, data: ControlOut<'a>) -> Result<(), Box<dyn Error>>;
async fn bulk_in(&self, endpoint: u8, buf: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>>; async fn bulk_in(&self, endpoint: u8, length: usize) -> Result<Vec<u8>, Box<dyn Error>>;
async fn bulk_out(&self, endpoint: u8, buf: Vec<u8>) -> Result<(), Box<dyn Error>>; async fn bulk_out(&self, endpoint: u8, data: Vec<u8>) -> Result<usize, Box<dyn Error>>;
async fn interrupt_in(&self, _endpoint: u8, _buf: Vec<u8>) { async fn interrupt_in(&self, _endpoint: u8, _buf: Vec<u8>) {
unimplemented!() unimplemented!()