BodgeUSBGadget

Be a USB device from Elixir on Linux. The device-side companion to bodge_usb (host-side USB): where that library talks to USB devices, this one makes the machine be one, on UDC-capable hardware (OTG ports on Pi Zero/4, BeagleBone, most Nerves targets, or dummy_hcd for a virtual UDC).

Two capabilities:

Example

spec = %{
vendor_id: 0xCAFE,
product_id: 0xBABE,
strings: %{manufacturer: "bodge", product: "demo", serialnumber: "g-1"},
functions: %{
"hid.usb0" => %{protocol: 0, subclass: 0, report_length: 8, report_desc: report_desc}
},
configs: %{"c.1" => %{configuration: "demo", max_power: 120, functions: ["hid.usb0"]}}
}
{:ok, g} = BodgeUSBGadget.define("demo", spec)
:ok = BodgeUSBGadget.bind(g)
{:ok, "/dev/hidg0"} = BodgeUSBGadget.device_node(g, "hid.usb0")

See BodgeUSBGadget.FunctionFs for the custom-function lifecycle (mount, descriptors, SETUP handler, endpoint files).

Requirements

Linux with configfs mounted, libcomposite and the usb_f_* modules for the functions used, a UDC, and root (or equivalent permissions on /sys/kernel/config).

Testing

mix test runs the host-safe suite anywhere (spec validation, configfs tree construction against a tmpdir, FunctionFS blob construction). The device-backed tests (:usbfs_gadget, :usbfs_ffs tags) exercise both roles end to end against dummy_hcd, with bodge_usb as the host driver; run them inside the bodge_usb VM harness (see harness/ in that repo) with mix test --only usbfs_gadget and mix test --only usbfs_ffs as root.

Installation

def deps do
[
{:bodge_usb_gadget, "~> 0.1.0"}
]
end