< All postsTwitterRSS GitHub

Apr 3 2020

Sending my alerts directly to the keyboard

I wanted a way to have a visual alert for if something I manage really badly breaks that would also be hard for me to miss.

I mentioned this idea to a friend and sent this picture of me having made a small demo to flash a red LED strip behind my desk using a little Raspberry Pi.

My keyboard

Then he replied with “Why not strobe the keyboard” which got me thinking about how difficult that would actually be. However my keyboard is a Ducky Keyboard which doesn’t really have any fancy support for Linux.

However that friend happens to be Ben Cox, who had written a blog post previously about writing userspace USB drivers for Linux. So I started by re-reading that blog post.

Following in the footsteps of that post, I set up a Windows 10 VM to see what the Windows application from the manufacturer actually did. It seems that the only way to download the DuckyRGB software is Google Drive, and that does not inspire confidence but I verified that it was the legitimate driver and continued on.

I started Wireshark on the USB device and launched the DuckyRGB software in the VM, I then began to look at the packets being sent and received.

Wireshark Capture

After spotting what looks like a version number in the USB packets and confirming that it matched what the original software said, I began writing my first attempt at the userspace driver to get a feel for it (since this is my first USB related project)!

$ sudo ./kb-alerter
Firmware Version: V1.01.05

I then tested changing the color of the backlight in the DuckyRGB UI while I monitored the USB packets coming out of the VM towards the keyboard. The keyboard UI was very nice and displayed the hex color code of the keyboard backlight, so I was able to just look for that in the Wireshark capture.

USB Color Packet

I then added a rough implementation of an Alertmanager HTTP endpoint to it and it was all working great, except… it didn’t actually work as a keyboard anymore.

This is due to the fact that to send interrupts to the keyboard to change the color, I need to claim the device, so the default kernel driver no longer has access to it. This obviously makes it stop working as a normal keyboard.

There is however a way to solve this problem, with hidapi using the Linux kernel’s hidraw api.

Introducing cynhid, very minimal bindings for hidapi in Go.

With cynhid I was able to send data to the keyboard without claiming the device, and as such I was able to use it as a normal keyboard at the same time!

As I learned while making this blog post, custom drivers are not always the best way to add custom functionality to USB devices on Linux, sometimes there are pre existing APIs that can make adding functionality a lot easier.

Despite me ending up not using a custom USB driver in the final version, it was still quite interesting to play around with, if for no other reason than I now have another trick up my sleeve for future projects.

And now thanks to my keyboard, I will never miss alerts again.

Assuming you also have a Ducky Keyboard, you can find the code for this project on github to try yourself here: https://github.com/bitcynth/kb-alerter

If this was to your liking then maybe you will find my other posts interesting, and you can also find my smaller projects and ramblings on twitter: @bitcynth.