Skip to content

Support discovery packets (00 00 control bytes) in frame parsing#48

Merged
marklynch merged 2 commits into
marklynch:mainfrom
lawther:feat/control_0000
Jun 25, 2026
Merged

Support discovery packets (00 00 control bytes) in frame parsing#48
marklynch merged 2 commits into
marklynch:mainfrom
lawther:feat/control_0000

Conversation

@lawther

@lawther lawther commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Note - Stacked on #47 (feat/sliding_window) — please merge that one first. This PR's diff currently includes #47's commit too; once #47 merges, it'll shrink down to just the new commit below.

Summary

  • The bus also sends a second, shorter frame shape: discovery packets with 0x00 0x00 control bytes (vs the usual 0x80 0x00 data packets), exactly 11 bytes with no payload and no separate data-checksum byte
  • Classify control bytes via a shared framing_classify_packet() helper (FRAMING_PACKET_DATA / FRAMING_PACKET_DISCOVERY / FRAMING_PACKET_INVALID) used by both framing.c and message_decoder.c, replacing scattered length checks (including a stale hardcoded 12-byte minimum that silently dropped valid 11-byte discovery packets)
  • This patch only adds the 00 00 control byte parsing, it does not add any new cmd parsing.
  • Closes observed: unknown control bytes #45

lawther added 2 commits June 25, 2026 11:57
Replace the all-or-nothing frame parser with a sliding-window resync: on a
bad header checksum, control bytes, length, end byte, or data checksum the
parser discards a single byte and retries, recovering valid frames from
stutters, cross-device collisions, and line noise (issue marklynch#46).

Framing logic moves into a dedicated, host-testable framing.c module; error
accounting is reworked from message-error counters into per-type resync
counters surfaced on the status page and tagged through the unknown-message
buffer.

Tests: golden-file harness seeded with the real captures from the issue,
plus chunked-input cases (| splits one case into multiple add_bytes calls)
and a chunk-invariance property sweep proving frame recovery is independent
of how the byte stream is fragmented across reads.
The bus also sends a second, shorter frame shape: discovery packets with
0x00 0x00 in the control bytes (vs the usual 0x80 0x00 data packets).
These are always exactly 11 bytes (header + END), with no payload and
no separate data-checksum byte - byte 9 is purely the header checksum.

Classify each frame's control bytes into FRAMING_PACKET_DATA,
FRAMING_PACKET_DISCOVERY, or FRAMING_PACKET_INVALID via a shared
framing_classify_packet() helper in framing.h/.c, then branch the
minimum-length and data-checksum logic in framing.c on that enum
instead of re-deriving control-byte state in multiple places.
message_decoder.c reuses the same classification to pick its own
minimum length and payload size, replacing a hardcoded len==11 check
and an independent 12-byte minimum that had been silently dropping
valid 11-byte discovery packets.

Add synthetic framing test cases for the new packet type (and the
negative case of the same shape with the wrong control bytes), and
extend the chlorinator/heater/touchscreen replay samples with real
captured discovery packets, which decode cleanly and fall through to
the generic "Unhandled" logger since none of their CMD bytes have a
registered handler yet.
@marklynch

Copy link
Copy Markdown
Owner

Looks great.

@marklynch marklynch merged commit 559f3a7 into marklynch:main Jun 25, 2026
2 checks passed
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.

observed: unknown control bytes

2 participants