Reverse Engineering a Bluetooth Fridge
How it started
This year I’ve been spending more time on outdoor adventures, so I got a small portable fridge for the car to skip the hassle of dealing with ice in traditional coolers.
The fridge is pretty much a cooler with buttons and a 12v power cord. I had no idea the fridge had Bluetooth when I ordered it, much less that I’d be digging deep into the guts of how it worked on yet another Raspberry Pi project.
Again, I had no plans to make this a project, but I estimated it’d be a simple device code-wise, and the little screen and buttons would make it easy to confirm what data changes happened. I decided it’d be the perfect opportunity to use Go to create a daemon that managed a bunch of sub-procedures, something I’ve been wanting to practice.
Later I found out the Go ecosystem had suitable libraries and I had the energy to build out a HomeKit device I actually use now. I’ll summarize the results below.
How it went
I finally got to know Bluetooth as a protocol and the general design of devices after brushing up against it over the years using Node.js or Arduino. This time was the right combination of interest and reasonable scope. I was pleasantly surprised to find the fridge had a small, quirky data representation that controlled everything via a single Bluetooth characteristic1. All I had to do was serialize data and write data frames to the Bluetooth stack.
What I arrived at after more probing with Wireshark was a near-complete understanding of how the fridge manufacturer’s Bluetooth app talked to the fridge. That’s codified in a Go package containing the fridge protocol.
From there I was able to build my fridge daemon for the Raspberry Pi, find some great software to expose my Bluetooth client as a HomeKit bridge, and build a basic deployment system using Ansible and the musl cross-compiler to develop and deploy features all from my mac.
The source code is on GitHub here: https://github.com/johnelliott/alpicoold
I’m trying to avoid starting big, time-sucking Raspberry Pi projects these days, yet this one was fruitful on these fronts:
- Cross compiling Go/cgo from x86 Mac to Raspberry Pi will be my new default Pi workflow2
- Learning Bluetooth & Wireshark was pure enjoyment
- Grokking quitting, cancellation and top-level structure for Go programs improved my Go skills in ways I’ll actually use when writing servers
Being able to start my fridge and see my home from afar is cool too :)
I may go into more detail in later posts, but I’ll leave this one as a summary for now. For good measure, here is what the fridge and UI look like:
A Bluetooth characteristic is a bit like an REST endpoint ↩︎
Needing to compile Go with libftdi for Windows in 2019 played a part in abandoning a previous project ↩︎