Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Framed Binary Protocol (toy format)

A clean-room Python library demonstrating byte-level protocol framing on an unreliable stream: a compact frame format, a table-driven CRC-8 integrity check, a strict encoder/decoder pair, and a stream decoder that survives garbage, torn frames and flipped bits by resynchronizing on a magic marker.

The wire format is an intentionally simple example protocol defined for this library — it does not correspond to any real device or vendor.

Frame layout

 0        1        2        3        4        5 .. 5+N-1   5+N
+--------+--------+--------+--------+--------+-----------+--------+
| 0xAB   | 0xCD   | type   |   length (LE)   |  payload  | CRC-8  |
| magic (2 bytes) | 1 byte |     2 bytes     |  N bytes  | 1 byte |
+--------+--------+--------+--------+--------+-----------+--------+
 \_________________________________________________________/
                  CRC-8 (poly 0x07, init 0x00)
                  covers every byte before it

Frame types: DATA=0x01, ACK=0x02, PING=0x03, ERROR=0xFF. Fixed overhead is 6 bytes per frame; payload is capped at 65 535 bytes by the 2-byte length field.

Modules

File Role
frame.py Frame dataclass (frozen, validating) + FrameType enum
crc.py CRC-8, 256-entry lookup table built at import (no per-byte bit loop)
encoder.py encode(Frame) -> bytes
decoder.py decode_one(bytes) -> (Frame, consumed) + StreamDecoder

Error handling & resynchronization

decode_one distinguishes incomplete from corrupt:

  • IncompleteFrame — the buffer ends mid-frame; read more and retry.
  • CorruptedFrame(position, reason) — pinpoints the first invalid byte and classifies it: bad-magic, unknown-type, or crc-mismatch.

StreamDecoder.push(chunk) accepts arbitrary chunks as they arrive from a transport, emits every completed valid frame, and on corruption resyncs by scanning forward for the next magic marker — including the subtle case where a lone first-magic-byte at the buffer tail must be kept because it may start the next frame. Corruption events are recorded in decoder.errors for logging/metrics rather than silently swallowed.

Usage

from frame import Frame, FrameType
from encoder import encode
from decoder import StreamDecoder

wire = encode(Frame(FrameType.DATA, b"hello"))

dec = StreamDecoder()
for chunk in (wire[:4], wire[4:]):          # bytes arrive fragmented
    for frame in dec.push(chunk):
        print(frame.type.name, frame.payload)

Tests

pip install pytest
python -m pytest test_framed_protocol.py -v

14 tests cover:

  • round-trip for every frame type, empty and 2 KiB payloads;
  • CRC-8 known-answer vector ("123456789"0xF4);
  • exhaustive single-bit-flip: flipping any one bit anywhere in a frame is detected (as CRC mismatch, bad magic, unknown type, or a torn frame);
  • incomplete frame at every possible truncation point;
  • resync after leading garbage, after a CRC-corrupt frame, and with a partial magic byte at the buffer tail;
  • back-to-back frames decoded from a single chunk.

Skills demonstrated

Binary protocol framing · CRC error detection (table-driven CRC-8) · stream desynchronization recovery · typed error reporting with byte-accurate positions · property-style exhaustive testing (bit flips, truncation points).


MIT-licensed, self-contained clean-room implementation — the frame format is an original toy example, not any third-party or product protocol.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages