
Raw Gadget is a kernel module that allows to emulate USB devices from userspace - SomeSnail
https://github.com/xairy/raw-gadget
======
XMPPwocky
A key bit of information that might clear up some confusion - USB gadgets are
the main _peripheral-side_ USB interface in the Linux kernel.

When you plug an embedded Linux device like a phone into something, it could
use USB gadgets to expose internal storage as a mass storage device, create a
tty and expose that as a USB ACM/CDC device, etc- and using the gadget
mechanism, allocate USB endpoints to each of these functions, and enable or
disable them at runtime.

So, this project seems to be allowing a Linux device to emulate arbitrary
peripherals to an external USB host.

Prior work in this area: see Facedancer. Neat.

~~~
Vogtinator
No, this allows userspace to act as a USB gadget connected to the Linux kernel
it's running on.

~~~
XMPPwocky
It sure doesn't seem to.

That's why they have a separate subproject for it-

[https://github.com/xairy/raw-
gadget/blob/master/dummy_hcd/RE...](https://github.com/xairy/raw-
gadget/blob/master/dummy_hcd/README.md)

But you certainly could know more than me about it! Why do you think it's
exclusively for acting as a USB gadget connected to the Linux kernel it's
running on?

~~~
Vogtinator
It looks like I'm only partially right: dummy_hcd is just for the local
kernel, but raw gadget is just yet another interface to the UDC, so like usb
functionfs just without sanity checks.

I found documentation about this in the submission to mainline:
[https://lwn.net/ml/linux-
usb/461a787e63a9a01d83edc563575b858...](https://lwn.net/ml/linux-
usb/461a787e63a9a01d83edc563575b8585bc138e8d.1579007786.git.andreyknvl@google.com/)

------
lmilcin
This is really fantastic. I am currently building my own keyboard with my own
controller and it will be much easier for me to first implement mock
controller in userspace before I try to get it right on external device.
Especially because I will want to put some complicated functionality in it
like steno.

~~~
jrockway
I don't think you need that for this. The keyboard firmware likely consists of
three big chunks, the USB code, the matrix scan, and the processing of the
matrix scan data into keystrokes. The USB stack is likely a peripheral on your
microcontroller, which they have in theory already tested. The matrix scan
will need to be tested on real hardware. The processing code should be
abstracted enough from USB and matrix scanning that you can just compile it
for your host machine and write tests the usual way (given matrix state x then
y, output state should be foo).

For final integration tests, you can use an additional microcontroller to be
the key matrix. Instead of wiring up keyswitches, wire the microcontroller to
the matrix pins, and have it accept commands over the serial port to set the
matrix to a certain state. This way, you can do a full end-to-end test on your
real hardware.

The only place USB gadget emulation might be helpful is in writing the code
that switches the keyboard from compatibility mode (6KRO) to the NKRO mode.
It's been done a million times, though, so there is plenty of library code to
just copy.

~~~
lmilcin
First, this is going to be my first USB device. Second, I plan to put some
more complex functionality. I intend it to be my last keyboard so I want to be
able to map every key however I want (the whole point of having my own
controller). I also want it to have built-in steno which is much more than
just matrix scanning.

While I could achieve all of that with OS driver and plover the sad reality is
that I am unable to install my own software on my corporate PC and I would
like to have consistent environment at my home and office.

~~~
jrockway
All I'm saying is that the interesting part of the code will run just fine on
your host machine, so you don't need any complicated tricks to develop and
test it. Obviously in production it will run on the microcontroller, so you
get the functionality you desire without OS drivers.

Do keep in mind that /usr/share/dict/words is about 10x larger than the flash
on microcontrollers. This is why most people do the steno conversion in
software, not on the keyboard itself.

~~~
lmilcin
I plan to store configuration data on an SD card for convenience.

If it wasn't clear yet it is my personal project, I don't plan to make product
from it.

~~~
ihuman
If you're not designing your own microcontroller, you might want to check out
the Proton-C. It has 248kB of usable flash memory, which could be enough to
store a stenography-optimized word list in addition to the firmware. It was
made to be flashed with the qmk keyboard firmware, but I don't think there's
any requirement that you have to use qmk.

[https://qmk.fm/proton-c/](https://qmk.fm/proton-c/)

~~~
jrockway
I used an STM32F103 for my last keyboard, and you can buy four for the price
of a Proton C. I am still not sure why they chose the F3 series for the Proton
C, as it doesn't seem to be a chip that's commonly used in the maker
community. I am somewhat surprised they didn't bite the bullet and just port
QMK to the nRF52 (since everyone wants bluetooth out of the box), actually.

The F103 is also interesting in that it is well-supported by Rust and Tinygo,
if C isn't your thing. I picked it because QMK supports it (and works great),
but I'm actually planning to write the firmware in Go and ditch all the things
that bug me about QMK. However the USB stack is not there and I dread writing
it. I might pull a QMK and just have ChibiOS run my Go code ;)

~~~
ihuman
The F3 series includes support for "analog peripherals," so maybe they decided
on that line so they could support the speaker? If that's correct, then that's
a pretty niche feature for them to focus on. There are forks of qmk and the
pro-micro that support the nRF52, but as far as I can tell nothing has been
merged into the main qmk yet.

------
zokier
Bit of clarification is apparently needed. The loopback USB emulation is
already in mainline via CONFIG_USB_DUMMY_HCD

What this new module provides is new userspace API to the gadget subsystem,
making the dummy hcd much more practical especially for testing USB driver
code

------
codebeaker
Could this be useful to "mock" A USB device for integration testing hardware
(or specifically writing specs against not-plugged-in-hardware)?

------
vrsfvwae5tbh
Could this be used to emulate a usb keyboard from untrusted code and break out
of a sandbox?

------
TorKlingberg
Neat. Can you clarify what "emulate" means? Would this let me implement a USB
gadget on a Linux board with a device-side USB port, without writing a kernel
module?

~~~
Vogtinator
That's already possible using usb functionfs.

------
Vogtinator
Arguably this can be implemented already using usbip to localhost. That's
already part of mainline, so does not need any out of tree modules.

------
RyanMathewson
Does anything like this exist for Windows? I was recently looking and couldn't
find anything.

