Reverse engineering the UE Boom bluetooth protocol

5 December 2019

I’m a happy owner of a UE Boom 2 bluetooth speaker, which conveniently sits in my bathroom for when I want to listen to music while taking a shower or shaving. I also enjoy atomating things, so it won’t come as a surprise that my entire home is automated through HomeKit and Homebridge: all my lights are in there, my hi-fi system, the turntable and so forth. The only piece of technology that was missing was the bathroom speaker, so I decided to hack it and make a homebridge plugin out of it.

I knew that the speaker could be turned on remotely (within range) using the proprietary Ultimate Ears app, and it was obvious that the bluetooth command was sent by the application itself.

Sniffing bluetooth commands

I first installed Apple’s Bluetooth logging profile on my iPhone, then connected it to the Mac via USB and used PacketLogger to trace the packages sent from the phone (specifically ATT Send type). By opening the UE app and tapping on the remote power button in it I was able to sniff the conversation between the phone and the speaker as shown in this screenshot.

PacketLogger Screenshot

The handle 0x0003 is the specific sequential number tied to the remote power feature, whereas the value 4098ADA356C401 is the bluetooth MAC address of my iPhone (40:98:AD:A3:56:C4) without semicolons followed by 01. I then retrieved the MAC address of the speaker and used gatttool on a Raspberry Pi to perform a write request, and BOOM I can turn on the speaker from my command line1.

gatttool -i hci0 -b $SPEAKER_ADDRESS --char-write-req -a 0x0003 -n ${HOST_ADDRESS}01

HomeKit integration

From here, I wrote a Homebridge-compatible plugin and published it on NPM to make it available to all the Homebridge users. The plugin itself is mostly boilerplate and wraps the aforementioned command in a javascript file where the characteristics of the HomeKit device are declared.

Plugin animation

You can find the package on NPM under the name homebridge-ueboom, or by clicking here. If you want to contribute, visit the GitHub repository.

Considerations and further improvements

Turning off the speaker is not yet possible as it requires rfcomm and I’ve been having some issues with it. As soon as I have time I’ll work on it. I also tried to repeat the procedure on a JBL Flip 3, unsuccessfully.

I don’t know the exact specifications of the UE Boom so this is pure speculation: the speaker itself has the usual Bluetooth 4.0 module that allows to stream music, in addition to that there’s also a BLE (Bluetooth Low Energy) module that for its own nature is always on and allows to turn the speaker on and off remotely (within range). The only reason why I’m not sure this is the real reason is that the two modules would probably have two separate MAC addresses, and from what I’ve observed there’s only one single address available.

  1. The gatttool command turns the speaker on but doesn’t associate the speaker with the Raspberry Pi. The speaker connects to the host device (in my case my iPhone).