#usb-device #usb #web-usb #web-api

cross_usb

A Rust USB library which works seamlessly across both native and WASM targets

11 unstable releases (3 breaking)

0.4.0 Aug 14, 2024
0.3.4 Jul 6, 2024
0.3.2 Apr 23, 2024
0.3.1 Mar 24, 2024
0.1.1 Jan 31, 2024

#181 in WebAssembly


Used in minidisc

MIT license

45KB
817 lines

Cross USB

Lib.rs Version docs.rs

A USB library which works seamlessly across most native and WASM targets.


[!NOTE] Web USB only works in Chromium based browsers for now.

[!NOTE] Web USB has certain interaction requirements in browsers, along with requiring a Secure context. Please read more about this on the mdn web docs

[!IMPORTANT] When compiling this crate on a WASM target, you must use either the rustflags RUSTFLAGS=--cfg=web_sys_unstable_apis or by passing the argument in a .cargo/config.toml file. Read more here: https://rustwasm.github.io/wasm-bindgen/web-sys/unstable-apis.html

Dependencies

For native USB, the crate utilizies nusb, a pure rust library similar to the very popular libusb.

For WASM, this crate utilizes web-sys which gives access to browser API calls, and in this case is used to interact with WebUSB

Example

To learn about how USB communciations work, check out USB in a NutShell.

use cross_usb::prelude::*;
use cross_usb::usb::{Recipient, ControlType, ControlIn};
use cross_usb::device_filter;

// Obtain a device descriptor using a DeviceFilter,
// in this case with its VendorID and ProductID
let filters = vec![
    device_filter!{vendor_id: 0x054c, product_id: 0x00c9}
];
let dev_descriptor = cross_usb::get_device(filters).await.expect("Failed to find device");

// Open the device that the descriptor is describing
let dev = dev_descriptor.open().await.expect("Failed to open device");

// Obtain an interface of the device
let interface = dev.open_interface(0).await.expect("Failed to open interface");

// Send a Control transfer to the device, obtaining
// the result and storing it in `result`
let result = interface.control_in(ControlIn {
        control_type: ControlType::Vendor,
        recipient: Recipient::Interface,
        request: 0x01,
        value: 0,
        index: 0,
        length: 4,
    })
    .await
    .expect("Sending control transfer failed");

Check out the documentation as well!

TODO

  • Add choice for native backend between libusb wrapper and pure rust nusb
  • Allow platform-specific operations if the user requires them
  • Hot plug support... requires either using libusb as an optional backend or for nusb to implement it

Dependencies

~0.3–15MB
~144K SLoC