#usb-device #usb #devices #web-usb #cross-platform #wasm-bindgen

cross_usb

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

10 releases

new 0.3.2 Apr 23, 2024
0.3.1 Mar 24, 2024
0.2.3 Mar 10, 2024
0.2.2 Feb 18, 2024
0.1.1 Jan 31, 2024

#234 in WebAssembly

Download history 5/week @ 2024-01-25 13/week @ 2024-02-01 133/week @ 2024-02-15 23/week @ 2024-02-22 7/week @ 2024-02-29 192/week @ 2024-03-07 23/week @ 2024-03-14 170/week @ 2024-03-21 31/week @ 2024-03-28 21/week @ 2024-04-04

223 downloads per month
Used in minidisc

AGPL-3.0

41KB
722 lines

Cross USB

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

Crates.io

Documentation


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

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

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

lib.rs:

Cross USB is a USB library which works seamlessly across native and WASM targets.

The idea is the user only has to write one way to access USB devices, which can be compiled to both WASM and native targets without any additional conditional compilation or configuration.

For native device support, this library uses nusb, a cross platform USB library written in Rust and comparable to the very popular libusb C library. Web Assembly support is provided by web-sys with the Web USB API.

When an Interface is dropped, it is automatically released.

CURRENT LIMITATIONS:

  • Hotplug support is not implemented. Waiting on hotplug support in nusb.

  • Until this pull request is merged into wasm bindgen, getting a list of USB devices is not possible on WASM targets. However, this isn't a huge deal as the user gets a list to select from anyway.

Example:

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");

Dependencies

~0.3–14MB
~148K SLoC