mirror of
https://github.com/G2-Games/cross-usb.git
synced 2025-04-19 13:22:53 -05:00
Fixed some problems with wasm
This commit is contained in:
parent
3bad540481
commit
db9605fbb7
4 changed files with 72 additions and 46 deletions
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(¶ms, length));
|
let promise = Promise::resolve(&self.device.control_transfer_in(¶ms, 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(¶ms));
|
let promise = Promise::resolve(&self.device.control_transfer_out(¶ms));
|
||||||
|
|
||||||
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
|
||||||
)
|
)
|
||||||
|
|
18
src/usb.rs
18
src/usb.rs
|
@ -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!()
|
||||||
|
|
Loading…
Reference in a new issue