From 37c80c382acd98010b067af9d8663c1982cfb7ff Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 5 Jul 2026 17:32:51 -0400 Subject: [PATCH] Fix config parser silently dropping NFC/flash after touch/buzzer The TLV config parser's default case jumps to the CRC (offset = configLen - 2) on any unrecognized packet ID, silently dropping every packet that follows. Silabs had no cases for 0x28 (touch_controller), 0x29 (passive_buzzer), or 0x2C (data_extended). The client emits touch/buzzer before flash (0x2B) and NFC (0x2A), so a config containing a touch or buzzer packet made Silabs abort mid-parse and never initialize its NFC + external-flash features. Add skip-by-size handling for these three packet IDs so later packets still parse. Silabs does not consume touch/buzzer (handled by the main MCU) or data_extended (host-only), so skip-by-exact-size is the minimum fix. Sizes cross-checked against Arduino structs.h, the Python config_serializer, and match the client wire format. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR --- opendisplay_config_parser.c | 56 ++++++++++++++++++++++++++++++++++++- opendisplay_constants.h | 10 +++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/opendisplay_config_parser.c b/opendisplay_config_parser.c index 713b41e..77ef7cf 100644 --- a/opendisplay_config_parser.c +++ b/opendisplay_config_parser.c @@ -366,6 +366,42 @@ bool parseConfigBytes(uint8_t* configData, uint32_t configLen, struct GlobalConf } break; + case CONFIG_PKT_TOUCH: // touch_controller (0x28) - handled by main MCU, skip on Silabs + if (offset > configLen) { + printf("Offset overflow before touch\r\n"); + globalConfig->loaded = false; + return false; + } + if (offset + CONFIG_PKT_TOUCH_SIZE <= configLen - 2) { + offset += CONFIG_PKT_TOUCH_SIZE; + if (offset > configLen) { + printf("Offset overflow after touch\r\n"); + globalConfig->loaded = false; + return false; + } + } else { + offset = configLen - 2; // Skip to CRC + } + break; + + case CONFIG_PKT_BUZZER: // passive_buzzer (0x29) - handled by main MCU, skip on Silabs + if (offset > configLen) { + printf("Offset overflow before buzzer\r\n"); + globalConfig->loaded = false; + return false; + } + if (offset + CONFIG_PKT_BUZZER_SIZE <= configLen - 2) { + offset += CONFIG_PKT_BUZZER_SIZE; + if (offset > configLen) { + printf("Offset overflow after buzzer\r\n"); + globalConfig->loaded = false; + return false; + } + } else { + offset = configLen - 2; // Skip to CRC + } + break; + case CONFIG_PKT_NFC: // nfc_config (0x2A) if (offset > configLen) { printf("Offset overflow before nfc_config\r\n"); @@ -423,7 +459,25 @@ bool parseConfigBytes(uint8_t* configData, uint32_t configLen, struct GlobalConf return false; } break; - + + case CONFIG_PKT_DATA_EXTENDED: // data_extended (0x2C) - host-only strings, skip on Silabs + if (offset > configLen) { + printf("Offset overflow before data_extended\r\n"); + globalConfig->loaded = false; + return false; + } + if (offset + CONFIG_PKT_DATA_EXTENDED_SIZE <= configLen - 2) { + offset += CONFIG_PKT_DATA_EXTENDED_SIZE; + if (offset > configLen) { + printf("Offset overflow after data_extended\r\n"); + globalConfig->loaded = false; + return false; + } + } else { + offset = configLen - 2; // Skip to CRC + } + break; + default: printf("Unknown pkt 0x%02X @%u\r\n", packetId, (unsigned)(offset - 2)); offset = configLen - 2; // Skip to CRC diff --git a/opendisplay_constants.h b/opendisplay_constants.h index fb2997b..74f81df 100644 --- a/opendisplay_constants.h +++ b/opendisplay_constants.h @@ -11,8 +11,18 @@ #define CONFIG_PKT_BINARY_INPUT 0x25 #define CONFIG_PKT_WIFI 0x26 #define CONFIG_PKT_SECURITY 0x27 +#define CONFIG_PKT_TOUCH 0x28 +#define CONFIG_PKT_BUZZER 0x29 #define CONFIG_PKT_NFC 0x2A #define CONFIG_PKT_FLASH 0x2B +#define CONFIG_PKT_DATA_EXTENDED 0x2C + +/* Wire sizes of config packets Silabs does not consume itself (touch/buzzer are + * handled by the main MCU, data_extended is host-only). They must still be + * skipped by their exact size so later packets (NFC 0x2A, flash 0x2B) parse. */ +#define CONFIG_PKT_TOUCH_SIZE 32 +#define CONFIG_PKT_BUZZER_SIZE 32 +#define CONFIG_PKT_DATA_EXTENDED_SIZE 288 #define CONFIG_CHUNK_SIZE 200 #define CONFIG_CHUNK_SIZE_WITH_PREFIX 202