Reverse Engineering of a BLE Bulb
I few months ago, I participated in the crowdfunding of a cheap Bluetooth Low Energy LED Bulb. Raised money was pitiful but project went ahead under a new name and I received my bulb anyway.
If you ask me, the name "Con Bulb" sounds odd both in English or in French (not for the same reasons) but this is not the point here so let's move on!
The website provides a link to apps (iOS and Android) but nothing else. These apps sort of work but since there is zero documentation, it's hard to guess what some functions/buttons are. And obviously, no info about the protocol used.
After a bit of research, I found that the light was basically a TINT B730 by Shenzhen LEDE Technology. And that the API seems totally proprietary.
Android to the Rescue
New versions of Android (>=4.4) have a nice feature called Bluetooth HCI snoop log. First, you need to activate the Developer Options by taping 7 times on Build number in your settings.
Then by activating the option "Bluetooth HCI snoop log", all the Bluetooth traffic will be recorded in a file (in /storage/emulated/0/Android/data/btsnoop_hci.log on my phone running Lollipop).
This file can then be read with Wireshark on a computer.
Decoding the data
All commands sent to the bulb follow a similar pattern:
For example here:
aa:0a:fc:3a:86:01:0b:01:08:5d:8d:0d
By matching the actions on the app to the BLE commands, I came up with a (incomplete but sufficient) list of commands.
API
Header
The header seems totally static and always
aa:0a:fc:3a:86:01
Trailer
The trailer seems totally static and always
0d
Commands
On
0a:01:01:00:28
Off
0a:01:00:01:28
White Reset
0d:06:02:80:80:80:80:80:RD:CS
White Mode - Brightness
0c:01:VV:RD:CS
Where VV = Brightness between 02 and 0b
White Mode - Colour Temperature
0e:01:VV:RD:CS
Where VV = Colour between 02 and 0b
RGB Reset
0d:06:01:80:80:80:80:80:RD:CS
RGB
0d:06:01:RR:GG:BB:80:80:RD:CS
Where RR, GG, BB are between 00 and FF
Preset/Memory mode
0b:01:MM:RD:CS
Where MM is a Preset mode:
- MM=01: Red
- MM=02: Green
- MM=03: Blue
- MM=04: Yellow
- MM=05: Pink
- MM=06: Cyan
- MM=07: White
- MM=08: Cycle of Primary Colours (Fast)
- MM=09: Cycle of Primary + Secondary Colours
- MM=0a: Cycle of Primary Colours (Slow)
Night Mode (Switches off after 20 minutes)
10:02:03:01:RD:CS
About RD & CS bytes
- RD seems totally random
- CS is apparently a checksum value equal to SUM(bytes composing the command including the random value + 0x1C) & 0xFF
For example, for preset #1 (Red) with a random value of 0x88:
CS = (0B+01+01+88 + 1C) & FF = B1
And for White Reset with a random value of 0x05:
CS = (0D+06+02+80+80+80+80+80+05 + 1C) & FF = 2B6 & FF = B6
Testing from the command line
Using a Bluetooth 4.0 USB Dongle, it is now possible to control the light directly from the computer...
- Starting Bluetooth (assuming HCI0)
hciconfig hci0 up
- Looking for the bulb:
hcitool lescan
should return something like:
D0:39:72:BE:12:34 (unknown)
D0:39:72:BE:12:34 B730
D0:39:72:BE:12:34 (unknown)
D0:39:72:BE:12:34 B730
- Connecting to the bulb:
hcitool lecc D0:39:72:BE:12:34
- Switching the light on:
gatttool -b D0:39:72:BE:12:34 --char-write-req -a 0x0021 -n aa0afc3a86010a010100280d
Python version
Using bluepy and a bit of Python, it is possible to control the light easily. Beware, the protocol is only partially implemented and communication is only unidirectional (computer to bulb) without waiting for any feedback. It might be a very bad idea to send commands at random (eg white temperature while in RGB mode) and/or too quickly.
Software can be found on github: https://github.com/guillier/BLE_RGB_LED_Bulb
Afterword
Other models of bulbs
It seems that reverse engineering of bulb is a popular sport these days. I found the following instruction for other models of lights:
- Reverse Engineering a Bluetooth Low Energy "colorific!" light bulb
- Bombilla "yeelight" LED de colores con Bluetooth Low Energy
Disclaimer
This page is for informational purposes only... You assume total responsibility and use at your own risk!