fix(firmware): phantom LD2410 detection + ENOMEM backoff (#1135) (#1159)

Bug #2 (root cause): LD2410 probe-detection matched only the 4-byte head
0xF4F3F2F1, so a floating UART at 256000 baud could phantom-detect a sensor
and spawn a UART task. Now requires a full validated report frame (head +
sane length + tail 0xF8F7F6F5), extracted to mmwave_detect.h and shared with
a host unit test (test_mmwave_detect.c, 8 vectors) so firmware and test can't
diverge. Matches the validate-before-trust approach used for MR60 in #1107.

Bug #1: sendto ENOMEM used a fixed 100 ms backoff too short to drain sustained
lwIP/WiFi buffer pressure, so a node could stay stuck. Now exponential
(100->200->...->2000 ms per consecutive ENOMEM, reset on first successful
send). Removing the phantom LD2410 task (bug #2) also removes the extra load
that tipped the reporter's tier-2 node into the stuck state.

Validated on ESP32-S3 QFN56 rev v0.2 (the reporter's silicon): tier-2 streams
~100 frames/s with no stuck ENOMEM and correctly reports no mmWave (no
phantom). LD2410 predicate truth table proven (head-without-tail REJECTED).
Could not reproduce the reporter's environment-specific floating-pin noise, so
the deterministic proof is the host unit test.
This commit is contained in:
rUv
2026-06-22 12:31:21 -04:00
committed by GitHub
parent 4bf88e1283
commit 7831f29436
5 changed files with 159 additions and 13 deletions
+7 -4
View File
@@ -26,6 +26,7 @@
*/
#include "mmwave_sensor.h"
#include "mmwave_detect.h"
#include <string.h>
#include <math.h>
@@ -401,10 +402,12 @@ static mmwave_type_t probe_at_baud(uint32_t baud)
}
}
}
/* LD2410: 4-byte header 0xF4F3F2F1 (already specific enough). */
if (i + 3 < len && buf[i] == 0xF4 && buf[i+1] == 0xF3
&& buf[i+2] == 0xF2 && buf[i+3] == 0xF1
&& baud == MMWAVE_LD2410_BAUD) {
/* LD2410: require a *full validated* report frame, not just the
* 4-byte head. A floating UART1 at 256000 baud can emit the head
* pattern 0xF4F3F2F1 from line noise (#1135 bug #2). The shared
* predicate (host-unit-tested in mmwave_detect.h) demands a sane
* intra-frame length AND the matching tail 0xF8F7F6F5. */
if (baud == MMWAVE_LD2410_BAUD && mmwave_ld2410_valid_at(buf, i, len)) {
ld2410_header_seen++;
}
}