Coder Social home page Coder Social logo

surban / usb-gadget Goto Github PK

View Code? Open in Web Editor NEW
61.0 2.0 6.0 157 KB

Expose standard or fully custom USB peripherals (gadgets) through a USB device controller (UDC) on Linux using Rust.

Home Page: https://crates.io/crates/usb-gadget

License: Apache License 2.0

Rust 99.80% Shell 0.20%
linux rust udc usb usb-device usb-functionfs usb-gadget

usb-gadget's Introduction

usb-gadget

crates.io page docs.rs page Apache 2.0 license

This library allows implementation of USB peripherals, so called USB gadgets, on Linux devices that have a USB device controller (UDC). Both, pre-defined USB functions and fully custom implementations of the USB interface are supported.

The following pre-defined USB functions, implemented by kernel drivers, are available:

  • network interface
    • CDC ECM
    • CDC ECM (subset)
    • CDC EEM
    • CDC NCM
    • RNDIS
  • serial port
    • CDC ACM
    • generic
  • human interface device (HID)
  • mass-storage device (MSD)

In addition fully custom USB functions can be implemented in user-mode Rust code.

Support for OS-specific descriptors and WebUSB is also provided.

Features

This crate provides the following optional features:

  • tokio: enables async support for custom USB functions on top of the Tokio runtime.

Requirements

The minimum support Rust version (MSRV) is 1.73.

A USB device controller (UDC) supported by Linux is required. Normally, standard PCs do not include an UDC. A Raspberry Pi 4 contains an UDC, which is connected to its USB-C port.

The following Linux kernel configuration options should be enabled for full functionality:

  • CONFIG_USB_GADGET
  • CONFIG_USB_CONFIGFS
  • CONFIG_USB_CONFIGFS_SERIAL
  • CONFIG_USB_CONFIGFS_ACM
  • CONFIG_USB_CONFIGFS_NCM
  • CONFIG_USB_CONFIGFS_ECM
  • CONFIG_USB_CONFIGFS_ECM_SUBSET
  • CONFIG_USB_CONFIGFS_RNDIS
  • CONFIG_USB_CONFIGFS_EEM
  • CONFIG_USB_CONFIGFS_MASS_STORAGE
  • CONFIG_USB_CONFIGFS_F_FS
  • CONFIG_USB_CONFIGFS_F_HID

root permissions are required to configure USB gadgets on Linux and the configfs filesystem needs to be mounted.

License

usb-gadget is licensed under the Apache 2.0 license.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in usb-gadget by you, shall be licensed as Apache 2.0, without any additional terms or conditions.

usb-gadget's People

Contributors

samcday avatar surban avatar windoze avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

usb-gadget's Issues

Set USB port max current to 900 mA on USB 3.0

Shouldn't the max power consumption for a USB 3 port be more than 500 mA? Or is this maxed to 500 mA by the linux gadget API? Or if the API only works on USB 2 ports?

return Err(Error::new(ErrorKind::InvalidInput, "maximum power must not exceed 500 mA"));

The amount of current draw for SuperSpeed devices are increased to 150 mA for low-power devices and 900 mA for high-power devices when operating in SuperSpeed mode.

https://www.maxrev.de/files/2014/08/usb_3_0_english.pdf - Section 9.2.5.1

Usage with HID gadget

Hi there,

Seems like a silly question but I've managed to create a HID device using the hid function builder.

But I can't see a way of writing to it... Is it just a case of opening the filepath on the OS for that hid device or whatever and writing to it? Or is there a way to write to it from within this module?

Dual Ethernet: same host_addr assigned to both device

Tests preformed on pi4 model B
kernel: 6.6.20+rpt-rpi-v8

Composite configurations with two net devices, with the same drivers, assign the same host mac address to both devices.
I believe this is an error with the Linux gadget module / kernel and not an issue with this repo.

When reviewing the files generated by rust, the host_addr variables are properly assigned, unique to each function.
I have the same issue when manually creating the configuration without this repo.

Is this the proper way, using this library, to configure a composite Linux device with two functions with the same driver?
Both devices enumerate on a windows machine. They have identical mac addresses.
Raising as an issue here to track the limitation in Linux gadget kernel capabilities.

I have been looking through the Linux kernel gadgets implementation and have not found any obvious culprits.
Working from the "gether_setup_name" function that assigns the host and dev addresses.
https://github.com/torvalds/linux/blob/20cb38a7af88dc40095da7c2c9094da3873fea23/drivers/usb/gadget/function/u_ether.c

Post on stack overflow tracking this error:
https://stackoverflow.com/questions/78270075/linux-gadget-universal-device-controller-dual-cdc-ecm-or-dual-rndis-ethernet

Code showing roughly how the rust library is being used.

let dev_addr1 = MacAddr6::new(0x66, 0xf9, 0x7d, 0xf2, 0x3e, 0x3b);
let host_addr1 = MacAddr6::new(0x7e, 0x21, 0xb2, 0xcb, 0xd4, 0x62);
let mut builder1 = Net::builder(NetClass::Ncm);
builder1.dev_addr = Some(dev_addr1);
builder1.host_addr = Some(host_addr1);
builder1.qmult = Some(10);
let (net1, func1) = builder1.build();

let dev_addr2 = MacAddr6::new(0x66, 0xf9, 0x7d, 0xf2, 0x3e, 0x4b);
let host_addr2 = MacAddr6::new(0x7e, 0x21, 0xb2, 0xcb, 0xd4, 0x71);
let mut builder2 = Net::builder(NetClass::Ncm);
builder2.dev_addr = Some(dev_addr2);
builder2.host_addr = Some(host_addr2);
builder2.qmult = Some(10);
let (net2, func2) = builder2.build();

let reg =
  Gadget::new(Class::new(0xEF, 0x02, 0x01), Id::new(0x5523, 0x2355), Strings::new("MyManufacturer", "MyProduct", "123456"))
      .with_config(Config::new("config").with_function(func1).with_function(func2))
      .bind(&udc)
      .expect("cannot bind to UDC");

Pls publish 0.7.0

I ran into the issue fixed by 897c511. I'll just pin to that commit for now but it'd be great if a version was published to crates.io :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.