18.3.2024 Získal jsem termostatickou hlavici Eqiva Smart CC-RT-BLE-EQ určenou jako náhradu běžných kohoutů na radiátorech ústředního topení, která je vybavena bezdrátovou konektivitou skrze BLE (Bluetooth Low Energy). Je napájená 2 tužkovými bateriemi AA a obsahuje malý komutátorový motorek s převodovkou (jak jinak než s plastovými kolečky), který ovládá pohyb tyčky ventilu. Zkusil jsem tedy hlavici namontovat na topení a po vložení baterek nechal provést kalibraci dorazů ventilu (bez toho se dále nedostanete). Motorek nemá žádný snímač polohy, projede několikrát tam a zpět a doraz se pozná zřejmě podle zvýšeného proudového odběru. Pak se na displeji objevila teplota a bylo možné provádět nastavení tlačítky a otočným knoflíkem. V menu jsem aktivoval BLE konektivitu a nainstaloval si do mobilu aplikaci Calor BT 1.4.1. Z nějakého důvodu si ta aplikace vynucuje přístup k poloze (aktivaci GPS), bez nějž odmítá fungovat, nicméně jí firewallem blokuju připojení k Internetu, takže nemá kam bonzovat. Před samotným použitím je potřeba nadefinovat místnost, kde je hlavice umístěná, pojmenovat ji a spárovat. Režim párování se na hlavici spustí zmáčknutím otočného knoflíku asi na 3 vteřiny, což je indikováno na displeji a v aplikaci by se měla objevit nová hlavice a pak je vyžadováno opsání čísla, které se objeví na displeji. Pak už všechno krásně fungovalo, mohl jsem nastavovat teplotu, různé režimy v kalendáři, atd.
Jelikož jsem ale šťoural, všiml jsem si v menu aplikace položky "Firmware Update" a tak jsem na něj hned nadšeně ťuknul. Předem vás varuju, nedělejte to! Aktualizace sice proběhla v pořádku a byl jsem informován, že je potřeba provést znovu párování, ale zde jsem tvrdě narazil. Po delším zmáčknutí otočného knoflíku místo párování jen zhasl displej a hlavice přestala reagovat na tlačítka. Oživil jsem ji až po vyjmutí a znovu-vložení baterií. Pak šla hlavice dál ovládat ručně tlačítky, ale pokus o párování vždy selhal tímto zátuhem. Zkusil jsem v menu vyvolat factory reset, ale nepomohlo to. Tak jsem šel hledat moudra na Internetu a na jednom německém fóru a v tomto vláknu na GitHubu si stěžovali na stejný problém i další uživatelé, ale nikdo nenašel žádné řešení.
20.3.2024 Podíval jsem se tomu tedy na střeva. Ty už někdo přede mnou docela detailně nafotil. Najdeme zde RF BLE SoC Cypress CYW20736 s jádrem ARM Cortex-M3, který obsahuje 320 kB ROM s BLE stackem a 60 kB RAM pro uživatelskou aplikaci. Jelikož nemá žádnou interní FlashROM, nahrává se aplikace po zapnutí přes rozhraní I2C či SPI ze sériové EEPROM resp. FlashROM. Zde ale žádnou takovou paměť nenajdeme. Druhým čipem je 8-bitový low-power MCU STM8L052C6 s 32 kB FlashROM, 2 kB RAM a řadičem LCD. Logicky by tedy měl být firmware pro BLE čip uložený právě v jeho flashce. Zatím nevím, po kterých pinech se BLE čip krmí.
Když jsem rozpitval androidí aplikaci Calor BT, našel jsem v ní 2 binární bloby res\raw\bleupdate.bin a res\raw\bleupdate_2.bin, které se mírně liší velikostí (cca 19 kB). Stáhl jsem si i starší verze aplikace a v Calor BT 1.2.3 jsem našel starší verzi BLE firmware blobů, která by snad mohla fungovat. Napadlo mě tedy zkusit dumpnout obsah flash paměti STM8 MCU a zkusit v něm najít umístění BLE FW blobu a přepsat ho. Na plošňáku jsem našel 2 programovací konektory (resp. řady testpointů) PRG1 a PRG2. První je vyvedený z STM8 a druhý z BLE čipu. Zapojení PRG1 jsem propískal snadno, ale u PRG2 je problém, že BLE čip nemá přístupné piny (QFN bez bočních faset).
PRG1 STM8 PRG2 CYW20736 1 GND 1 +Vbat 2 RST# (MCU pin 2) 2 BLE debug UART output 3 +Vbat 3 ? (trvale L) 4 SWIM (MCU pin 1) 4 GND 5 ? (trvale H)
Kolega mi půjčil nějaký čínský ST-Link V2 s podporou 1-drátového rozhraní SWIM, kterým jsem se k MCU připojil. Pak jsem si nainstaloval programovací software STVP (ST Visual Programmer) a zkusil paměť vyčíst, ale bohužel jsem zjistil, že je aktivní ROP (ReadOut Protection). ROP lze sice deaktivovat, ale smaže se tím celá paměť a pak bych z toho měl úplnou cihlou. Ještě doplním, že tento STM8 MCU má i bootloader po UARTu (nemá klasický boot pin, zapíná se v option Bytech), s kterým lze komunikovat např. pomocí programu STM8GAL, ale ten je přes ROP pochopitelně též zamčený. Z běžícího programu je však možné ho potenciálně spustit skokem na určitý entrypoint. Také jsem zjistil, že u některých STM8 MCU, které mají přístupný výstup vnitřního LDO (což není tento případ), se pomocí injektáže krátkých glitchů/poklesů napájení podařilo docílit narušení čtení option Bytů po resetu tak, že se ROP deaktivovala. Docela zajímavé čtení je zde a zde.
STVP_CmdLine.exe -BoardName=ST-LINK -Port=USB -ProgMode=SWIM -Device=STM8L052C6 -readOption -verbose STVP_CmdLine version 1.6 Verbose ON Log activity ON Display Progress OFF Message box warning if protect option byte ON Loop mode ON Erase device OFF Blank check device OFF Verify device ON Configuration: BoardName=ST-LINK ST-LINK_ID=0 Device=STM8L052C6 Port=USB ProgMode=SWIM Hit 'Esc' key to abort during communication. >>> Reading OPTION BYTE Cut Version and Revision of device: 2.1 (API) ERROR : The device is protected (API) WARNING : Operation aborted <<< Reading OPTION BYTE fails
Dále jsem čmucháním osciloskopem zjistil, že na pinu 2 konektoru PRG2 se nachází výstup debug/trace UARTu z BLE čipu na rychlosti 115200 baudů, kde se lze dočíst dost zajímavých informací o tom, co se zrovna děje v BLE aplikaci (řada zpráv mi byla povědomá z prohlížení BLE FW blobu). Také jsem zjistil, že BLE ještě funguje, ale zřejmě díky nekompatabilitě nového FW v BLE čipu a v STM8 MCU se rozhodila konzistence nastavení v menu, takže když nastavím BLE ON, tak je vypnuté a když OFF, tak se zapne a advertisuje. Podařilo se mi ho naskenovat (má název "CC-RT-BLE") a připojit se k němu pomocí šikovné ladicí BLE aplikace nRF Connect. Přes tuto aplikaci lze číst a zapisovat různé atributy a charakteristiky, které BLE zařízení poskytuje. Zkoušel jsem znovu Factory Reset zápisem Byte F0h do charakteristiky s UUID 3FA4585A-CE4A-3BAD-DB4B-B8DF8179EA09, jenž se provedl stejně jako přes volbu tlačítky, ale ničemu to nepomohlo.
Zkoušel jsem zachytávat různé zprávy na UARTu při různých akcích, jako např. zapnutí a vypnutí BLE v menu, při advertisingu, při připojení a odpojení protistrany a zápisu charakteristiky a samozřejmě také při vyvolání párování. Jak je vidět na 3. oscilogramu a logu níže, začne BLE aplikace opakovaně chrlit zprávy, že dostala nějaký příkaz, kterému nerozumí a program v STM8 MCU se z toho asi sesypal do nějakého assertu.
UART 115200 advertising packet pairing start deadlock
GPIO-Interrupt detected GPIO: TRUE INTERRUPT CALLBACK handler started! read data from UART fd Startsign detected read data from UART 91 Unknown MessageType INTERRUPT CALLBACK handler started! read data from UART 7e '~' read data from UART 67 'g' GPIO-Interrupt detected GPIO: FALSE GPIO-Interrupt detected GPIO: TRUE INTERRUPT CALLBACK handler started! read data from UART fd Startsign detected read data from UART 91 Unknown MessageType INTERRUPT CALLBACK handler started! read data from UART 7e read data from UART 67 GPIO-Interrupt detected GPIO: FALSE GPIO-Interrupt detected GPIO: TRUE INTERRUPT CALLBACK handler started! read data from UART fd Startsign detected read data from UART 91 Unknown MessageType
Jako jediná možnost, jak z toho ven, mě napadá najít piny, po kterých STM8 MCU láduje FW do BLE čipu, ty odpojit a připojit k BLE čipu nějakou paměť s nahranou starší verzí FW, pak by mohlo párování proběhnout. Před případným flashování BLE FW z aplikace bych musel za chodu přepojit odpovídající piny BLE čipu zpět k STM8 MCU.