fix(13e6): X-Draw-Pending recovery handshake + CDC serial routing
When drawNeeded survives a power-loss-mid-draw, send X-Draw-Pending: 1 on the next poll so the server suppresses rotation advancement (incl. the X-Boot-Reason: cold force-resync) and returns the SAME image back. Without this, cold-boot rotation defeats the existing 304-with-drawNeeded recovery branch — the device chases a fresh image every reset and the 13.3 panel ends up showing torn frames as draws keep getting interrupted. Also enable ARDUINO_USB_CDC_ON_BOOT=1 for the 13.3 env so Serial routes through the S3's native USB-CDC (visible as the "Espressif USB JTAG serial debug unit" ACM port when awake). Without this, Serial goes to UART0, whose pins aren't wired to either USB endpoint on the 13.3E6 board — making firmware logs invisible over USB and forcing reliance on server-side telemetry alone. Adds two unit tests covering header-present-when-set and absent-when-clear. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -608,6 +608,41 @@ void test_fw_bootstrap_loop_iterates_when_no_image() {
|
||||
TEST_ASSERT_TRUE(g_deep_sleep_started);
|
||||
}
|
||||
|
||||
// FW-DRAWPENDING-A: when drawNeeded is set in NVS at boot, the poll must
|
||||
// carry X-Draw-Pending: 1. Server uses this to suppress rotation advancement
|
||||
// (incl. cold-boot force-resync) so the device gets the SAME image back and
|
||||
// can retry the interrupted draw from the cached /img.bin. Without the
|
||||
// header, cold-boot rotation defeats the 304-with-drawNeeded recovery branch.
|
||||
void test_fw_draw_pending_header_when_draw_needed_set() {
|
||||
prefs.begin(NVS_NAMESPACE, false);
|
||||
prefs.putInt(NVS_KEY_DRAW_NEEDED, 1);
|
||||
prefs.putInt(NVS_KEY_SCHEMA_V, NVS_SCHEMA_VERSION); // skip migration noise
|
||||
prefs.end();
|
||||
g_http_response_headers["X-Image-Id"] = "1";
|
||||
|
||||
normal_operation_impl(String("mac"), http, String("url"), prefs);
|
||||
|
||||
TEST_ASSERT_TRUE_MESSAGE(
|
||||
g_http_request_headers.find("X-Draw-Pending") != g_http_request_headers.end(),
|
||||
"X-Draw-Pending header must be present when drawNeeded is set");
|
||||
TEST_ASSERT_EQUAL_STRING("1", g_http_request_headers["X-Draw-Pending"].c_str());
|
||||
}
|
||||
|
||||
// FW-DRAWPENDING-B: in the normal case (drawNeeded == 0), the header is
|
||||
// absent. The server treats absence as "device is happy, you may rotate."
|
||||
void test_fw_draw_pending_header_absent_when_no_draw_needed() {
|
||||
prefs.begin(NVS_NAMESPACE, false);
|
||||
prefs.putInt(NVS_KEY_SCHEMA_V, NVS_SCHEMA_VERSION);
|
||||
prefs.end();
|
||||
g_http_response_headers["X-Image-Id"] = "1";
|
||||
|
||||
normal_operation_impl(String("mac"), http, String("url"), prefs);
|
||||
|
||||
TEST_ASSERT_TRUE_MESSAGE(
|
||||
g_http_request_headers.find("X-Draw-Pending") == g_http_request_headers.end(),
|
||||
"X-Draw-Pending header must be absent when drawNeeded is clear");
|
||||
}
|
||||
|
||||
// FW-12/13: AP SSID derivation via ap_ssid_from_mac()
|
||||
void test_fw12_ap_ssid_from_mac_aabbcc() {
|
||||
String ssid = ap_ssid_from_mac(String("AA:BB:CC:DD:EE:FF"));
|
||||
@@ -661,5 +696,7 @@ int main(int argc, char** argv) {
|
||||
RUN_TEST(test_fw_panel_id_header_value_matches_macro);
|
||||
RUN_TEST(test_fw_bootstrap_loop_exits_after_deep_sleep);
|
||||
RUN_TEST(test_fw_bootstrap_loop_iterates_when_no_image);
|
||||
RUN_TEST(test_fw_draw_pending_header_when_draw_needed_set);
|
||||
RUN_TEST(test_fw_draw_pending_header_absent_when_no_draw_needed);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user