Skip to content

Fix config parser dropping packets after unknown TLV types#1

Open
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/config-parser-skip-unknown-packets
Open

Fix config parser dropping packets after unknown TLV types#1
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/config-parser-skip-unknown-packets

Conversation

@balloob

@balloob balloob commented Jul 5, 2026

Copy link
Copy Markdown

Problem

parseConfigBytes() in config_parser.c walks the TLV config as a switch on packetId, and its default case does offset = configLen - 2 (jump to the CRC) and stops. So on the first packet ID it doesn't recognize, it silently drops every packet that follows.

nRF has no case for these packet IDs:

ID Type
0x28 touch_controller
0x29 passive_buzzer
0x2A nfc_config
0x2B flash_config
0x2C data_extended

The client emits touch (0x28) before other packets, so a config with touch present makes nRF abort at 0x28 and lose the display/LED/sensor/etc. packets after it — the device parses an incomplete config.

Fix

Add cases for these five IDs that skip past the packet by its correct on-wire size and continue the loop, instead of aborting. nRF does not functionally use these features, so skip-by-size is sufficient to stop the truncation. default remains as the last-resort abort.

Sizes (all packed structs, cross-referenced)

ID Type Size Source
0x28 touch_controller 32 Arduino struct TouchController (structs.h); client serialize_touch_controller
0x29 passive_buzzer 32 Arduino struct PassiveBuzzerConfig; client serialize_passive_buzzer
0x2A nfc_config 32 Silabs struct NfcConfig (opendisplay_structs.h); client serialize_nfc_config
0x2B flash_config 32 Arduino/Silabs struct FlashConfig; client serialize_flash_config
0x2C data_extended 288 Arduino struct DataExtended (9 × 32); client serialize_data_extended

Testing

The nRF ARM toolchain (arm-none-eabi-gcc) is not available in my environment, so the full firmware image was not built. I verified the parse-loop logic instead with a standalone host-gcc simulation reproducing the loop: a config containing touch (0x28) + flash (0x2B) + data_extended (0x2C) followed by a display packet now parses all packets and reaches the trailing display packet, where previously it aborted at 0x28. Types, struct sizes, and the new CONFIG_PKT_* constants were checked manually against the existing code.

Related

The Silabs firmware has the analogous gap (no case for 0x28/0x29/0x2C); a companion PR addresses that side.

🤖 Generated with Claude Code

https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR


Companion PR: OpenDisplay/Firmware_Silabs#6 (same MJ-8 fix, Silabs side — 0x28/0x29/0x2C). Sizes cross-validated: both derived 0x28=32, 0x29=32, 0x2C=288 independently.

The TLV config parser aborted on the first packet ID it did not
recognize by jumping straight to the CRC (offset = configLen - 2),
silently dropping every packet that followed. nRF had no case for
packet IDs 0x28 (touch), 0x29 (buzzer), 0x2A (nfc), 0x2B (flash) or
0x2C (data_extended), so any config containing one of these (e.g.
touch emitted before other packets) truncated parsing.

Add cases that skip these unused packet types by their correct
on-wire size and continue, so subsequent packets are still parsed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant