Hacking the Thotcon 0xB Badge (Part 1 of ??)
2021-10-10
The Badge: First Impressions
God this thing is annoying. Im honestly amazed that for a conference that asks for silence during talks they made a badge that would play Entrance of the Gladiators on command.
However, it did seem pretty neat, and there were immedately a number of mysteries that jumped out at me that I wanted to uncover, or at least get more information on.
The design of the badge had at moments lead me to think that it would need to be damaged in some way to work on it, such as with the solder mask on the seat number field. I was honestly inches away from scratching the mask away by hand with a sharp object before I had gone to the "Hacking the Thotcon Badge" talk, which more clearly explained what could be done with it and how.
The rest of this will basically be a tutorial on how to get the dev environment set up, followed by a follow through of my process on how to turn this thing into a crappy bluetooth controller. (So crappy god please help.) I'm going to assume that most people who end up here have done so because they are interested in what can be done with this nice devkit they just got, and not people who have been around the block before, so I'll start from the very top.
The Basics
The first X track talk of the event was on how to work with the thotcon badge. While I had worked with arduino and the arduino IDE(god I loath the arduino IDE) before, I had never worked with espressif packages, and honestly I dont think I would have been able to get any of my project done if not for the talk guiding me through setting up the honestly painful dev environment.
In order to properly use the espressif system, the first thing to do is to download the Arduino IDE. This IDE is a full toolchain that goes from compiling, to linking, to flashing your code to whichever device you have decided to attack. There happens to exist an espressif toolkit for the arduino IDE that allows you to use it for their chips as well.
After that, we need to configure it to support espressif boards/chips. We can do that through the use of the following link:
https://dl.espressif.com/dl/package_esp32_index.json
In the configuration of the arduino IDE, under the preferences, you can find a field labled "Additional Board Manager URLS". You want to put the link above there, as that will add it into the list of repositories that it checks for finding board configurations. After this, you can go to Tools > Boards > Boards Manager
, search for esp32
and then click install. By default it should download the newest verison, which is what you want.
Finally, open the Tools menu, select the ESP32 Dev Module
from the ESP32 arduino list, and you should be good to go.
At this point I recommend you check out the following resources and confirm you can send them to your board before you do anything else:
- The Sample projects provided at the How to hack your board talk
- Im going to add the link to the default badge firmware here once it becomes available.
With that alone, you should be able to hack on the board all you want! Go crazy and see what you can do.
Some additional links I found helpful or at least are probably worth a further looking-into
- Some snippets of code, not all of which I could get working
- The espressif github, full of documentation and codesnips (I actually just noticed while writing this that there is a more up-to-date version of the espressif board package on their github with substantial documentation on it, I havent looked into it just yet but that seems like a good place to begin for a part 2 of this series.
- The ESP32 datasheet
The Plan
So one of the things that the ESP32 has is a full bluetooth stack, and maybe the video was still just on my mind but I thought back to the video by Ben Eater about The HID interface for USB (Well technically its about n-key rollover but he explains a lot of the HID stack along the way) and I had gotten it into my head that well, this board already looks like a controller, why not make it one? In addition the example script in the event was one that reacted to the button presses and had already figured out a good threshold for the triggering of the buttons, so I decided that it would be perfect to modify it to send those presses over Bluetooth HID.
Implementation
The first step was dissecting the documentation on the esp32 bluetooth. As I am writing this I dont remember too much of what I read, but I do remember trying to copy over some of the snippets of code in the /nkolban/esp32-snippets
github that I was unable to get working as a result of the .h
files it references not being in the environment. I want to do more testing with this, but because I couldnt get it working I instead moved to using the ESP32 BLE-Keyboard library by T-vK.
This ended up working! I was able to pair my laptop to the device and begin sending keyboard inputs. I added in a basic hold check debouncer and a way to enable and disable the sending of inputs, as I assumed that I wouldnt want to be running the bluetooth all of the time. This was when debugging hell began however.
Troubles and the danger of random libraries
I havent tested with it yet but I suspect that most of these issues will be resolved when I transfer over to the updated .json on the /espressif/arduino-esp32
library.
Trying to actually utilize the T-vK library had quite a few issues. For one its heavy. Simply adding it to the codebase increase the compilation and transfer time to over double the original length. In addition it clearly has quite a few issues that cannot be resolved without hacking on the library itself.
It has a .end()
command for the bluetooth controller, however the function is a NOP, it does nothing at all!! Why would you put that into a codebase instead of simply not including the function in the first place. I realized this after I had needed to change the battery due to undervoltage killing my project. Probably becasue the bluetooth stack was never going into hibernation mode.
Next, it doesn't seem to properly complete the pairing protocol. When I attempt to pair it, it connects to the host device, but quickly the host device complains about failure on setup, but then it still is connected and refuses to disconnect or be removed while it is still on. The library doesn't expose any way to handle a disconnect message or connect attempt in order to handle these gracefully, so I have to assume these methods are simply broken.
Finally I have noticed strange behavior in my code in that it takes time to "warm up" before it is ready to actually send the HID events to the user. I cant seem to identify the cause, however it feels like viewing the serial monitor has a habit of kicking the bluetooth stack into gear and once it sends its first keypress, all the other ones work fine.
The code itself
I don't think theres too much to talk about with the specifics of the code, as much as I would really like to. Its poorly commented and even worse formatted because it was all rushed to be at least workable during the event. I want to clean it up and probably remove the abstraction layer over the HID protocol. I know it well enough to implement it myself instead of using someone elses, and hopefully that would help clear up the issues I was having with the stack.
The last thing I want to do is attempt to figure out what is up with esp_log_set_vprintf()
and esp_log_level_set()
. There seems to be a way to pipe internal debug information out to the serial port, but given that there is no Serial.vprintf
command, I might have to spin a custom wrapper of vprintf to get the debug messages to bubble to the surface?
Either way its more testing to be done. Here's my code, patches and questions welcome. I will probably be pushing to it some over the next few weeks as I figure things out, and hopefully I figure out enough to warrent another post about it.
Thanks!