Reverse-engineering van BLE-data van de Bluetooth BBQ-thermometer IDT-34c-B met Arduino R4 WiFi

27 augustus 2024

Voor een van mijn projecten heb ik een datalogger nodig die draadloos temperaturen tot 270°C kan meten op drie locaties in een bewegend object. Een praktische oplossing hiervoor leek mij een zogenaamde BBQ-thermometer, die is voorzien van vier thermokoppels, een centrale meetmodule met display en Bluetooth 5.1-datatransmissie.

Aangezien de meetmodule benaderbaar is via een Android- of iOS-app, leek het mij mogelijk om de Bluetooth-gegevens draadloos te onderscheppen en op te slaan in een eigen meetdatabase. De meetmodule is vriendelijk geprijsd (€35) en goed verkrijgbaar. Het betreft een Inkbird, model IDT-34c-B: uitleesbaar tot op ruim 50 meter afstand, meetbereik van -30 tot 300°C met een precisie van ±1°C, en werkt op 2 AA-batterijen. Uit de specificaties blijkt ook dat het BLE 5.1-protocol wordt ondersteund, wat de kans op het automatisch uitzenden van de gemeten temperaturen aannemelijk maakt. En daarmee begint een interessant zoekproces.

Binnen de BLE-standaard zijn het GATT (Generic Attribute Profile) en ATT (Attribute Protocol) data-workflow gedefinieerd, waarmee op gestandaardiseerde wijze kan worden gescand of er Bluetooth-apparaten in de buurt zijn. Tevens kan op een standaard manier worden geselecteerd en gefilterd van welke data-attributen gegevens moeten worden verzameld. Met de Nordic nRF Connect en de BLE Scanner-app ontdekte ik al snel dat de meetmodule regelmatig de verzamelde gegevens uitzendt (advertising). Ook ontdekte ik dat de gemeten data zich bevindt in: Service ff00 en Characteristic ff01. Vervolgens wordt de data overgedragen als een 11-byte datapakket, waarin de metingen van elk van de vier thermometers worden weergegeven. Alleen blijkt de opbouw van dit 11-byte datapakket niet aan enige standaard te voldoen. Ik besloot een e-mail te sturen naar de leverancier met de vraag of er documentatie beschikbaar is over de wijze waarop de data is opgeslagen in het 11-byte datapakket. Binnen 24 uur ontving ik het antwoord: “Hello, sorry we do not provide the information you need. Cassie”. Op naar de volgende stap…

Ik besloot het datapakket te reverse-engineeren. Hiervoor heb ik een serie van 20 metingen uitgevoerd, waarbij ik een logische samenstelling van temperaturen en de thermometer waarmee de meting is opgenomen, gebruikte. In Excel maakte ik een tabel met daarin voor elk datapakket een uitsplitsing van de 11 bytes. Na heel wat gepuzzel bleek dat de wisselende gegevens zich bevinden in byte 2 tot en met 9. Ook bleek dat de eerste byte het minst significante bit is en de tweede het meest significante bit. Hiervoor kan een handige instructie worden gebruikt: int16_t probe1 = (data[1] << 8 | data[0]). In de werking wordt data[1] 8 bits naar links verschoven, waardoor het in de hoge byte van het 16-bits getal terechtkomt. data[0] blijft in de lage byte. Vervolgens worden deze twee bytes gecombineerd tot één 16-bits geheel getal.

In de C++-code start ik met het activeren van de BLE Bluetooth-module, waarna ik de scanfunctie inschakel. In de resultaten van de scanfunctie zoek ik naar de Inkbird meetmodule. Binnen de module filter ik op service UUID ff00 en characteristic UUID ff01. Met de characteristic.read() haal ik de 11-byte waarde op, waarin de vier gemeten waarden van de meetprobes zich bevinden. Nadat deze bytes zijn uitgelezen, zet ik ze om naar floating-point variabelen en maak ik de waarden beschikbaar om weer te geven in de seriële console en op te slaan in een lokale dataset.

Hiermee is de code voor mijn datalogger klaar. Een ervaring in het reverse-engineeren van Bluetooth BLE rijker. Het doorgronden van de opzet van BLE GATT- en ATT-protocollen biedt veel mogelijkheden voor het maken en uitlezen van sensoren die langdurig op batterijen kunnen werken. Reverse-engineeren is als een soort puzzel: je weet dat er een antwoord te vinden is, maar je weet ook dat de weg naar het antwoord uitdagend is en met vallen en opstaan uiteindelijk kan worden opgelost. Leuk en vooral ook leerzaam om te doen.