terseCRSF: valida lunghezza + CRC8 in decodeTelemetry; suite di test riallineata

- decodeTelemetry() ora scarta frame incompleti o con CRC8 errata (prima non
  validava nulla: frame corti/corrotti da ESP-NOW venivano decodificati
  leggendo oltre il frame -> telemetria spazzatura, e OOB read su FLIGHT_MODE).
- test_decode.cpp: vettori ricostruiti come frame reali con CRC valida
  (calcolata offline), battery ri-quadrato a lth=10, assert bat_fuel_drawn
  corretto a 350 (era 89678, pre-patch uint24), test "non valida CRC" invertito
  in "rigetta CRC errata", aggiunto test su frame troncato.
- Emulatore (03) e backpack reale usano lo stesso framing/CRC -> passano.

DA RI-ESEGUIRE A BANCO: 'pio test -e esp32dev_test' e test RF reale. Se la
telemetria reale sparisce, il backpack potrebbe non rilasciare una CRC valida
nel frame ESP-NOW -> in tal caso ripiegare su validazione solo-lunghezza.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Francesco Zanin
2026-06-23 19:39:02 +02:00
parent 67933bcfc1
commit bb378f16d0
3 changed files with 57 additions and 35 deletions

View File

@@ -352,7 +352,18 @@ void CRSF::sendSBUS()
//========================================================
uint8_t CRSF::decodeTelemetry(uint8_t *_buf, uint8_t len)
{
uint8_t crsf_frm_lth = _buf[1];
// PATCH LOCALE: validazione lunghezza + CRC8 prima di decodificare.
// L'upstream non valida nulla qui (la CRC era controllata solo in
// readCrsfFrame(), non usato perche' i frame arrivano da ESP-NOW): un
// frame corto o corrotto veniva decodificato leggendo byte oltre il
// frame e producendo telemetria spazzatura. 'len' = byte disponibili.
// _buf: [0]=sync [1]=lth(type+payload+crc) [2]=type ... [lth+1]=crc
uint8_t crsf_frm_lth = _buf[1];
if (len < 4) return 0;
if (crsf_frm_lth < 2) return 0; // almeno type+crc
if ((uint16_t)crsf_frm_lth + 2 > len) return 0; // frame non completo
uint8_t calc_crc = crc8_dvb_s2_sbuf_accum(&_buf[2], crsf_frm_lth - 1);
if (calc_crc != _buf[crsf_frm_lth + 1]) return 0; // CRC errata -> scarta
uint8_t crsf_id = _buf[2];
if (crsf_id == 0)
{

View File

@@ -12,6 +12,10 @@
// - terseCRSF.cpp, BATTERY_ID: bat_fuel_drawn leggeva 4 byte
// (bytes2int32) includendo il byte "percent" come LSB e gonfiando i
// mAh consumati (es. 350 -> 89678). Corretto a lettura uint24 a 3 byte.
// - terseCRSF.cpp, decodeTelemetry(): aggiunta validazione lunghezza +
// CRC8 in testa. L'upstream non validava nulla (frame corti/corrotti da
// ESP-NOW venivano decodificati leggendo oltre il frame). Ora un frame
// incompleto o con CRC errata viene scartato (return 0).
//
// Per aggiornare la lib upstream: ri-applicare queste patch a mano.
// ============================================================