@serialpilot/hdlc
v0.1.0
Published
Pure-function HDLC byte-stuffing framer/unframer with optional CRC-16/CCITT-FALSE FCS (PPP, MAVLink, AX.25). Browser-clean — no node:* imports.
Maintainers
Readme
@serialpilot/hdlc
Pure-function HDLC byte-stuffing framer/unframer with optional CRC-16/CCITT-FALSE FCS — the framing layer used by PPP, MAVLink, and AX.25. No node:* imports — runs unchanged in browsers and Web Serial.
Install
npm install @serialpilot/hdlcUse
import { frame, unframe } from '@serialpilot/hdlc'
const payload = new Uint8Array([0x01, 0x7e, 0x42, 0x7d])
// CRC-16/CCITT-FALSE FCS appended (default)
const wire = frame(payload)
const back = unframe(wire)
// → Uint8Array(4) [0x01, 0x7e, 0x42, 0x7d]
// FCS disabled
const wireRaw = frame(payload, { fcs: 'none' })
const backRaw = unframe(wireRaw, { fcs: 'none' })Wire format
| stuffed(payload + FCS₂) | 0x7E |- The trailing
0x7Eis the frame delimiter (FLAG). - Byte stuffing replaces
0x7Eand0x7Dinside the body with0x7D 0x5Eand0x7D 0x5Drespectively. - When
fcs: 'crc16-ccitt'(default), the 2-byte CRC-16/CCITT-FALSE of the payload is appended little-endian before stuffing, matching the PPP/MAVLink convention.
Options
frame(payload) // default: fcs = 'crc16-ccitt'
frame(payload, { fcs: 'none' }) // raw byte-stuffing only
unframe(frame, { fcs: 'crc16-ccitt' }) // verify FCS, throw on mismatch
unframe(frame, { fcs: 'none' }) // unstuff onlyErrors
unframe throws HdlcError for malformed input:
| code | meaning |
| ----------------- | ------------------------------------------------- |
| FCS_MISMATCH | computed CRC ≠ received FCS. |
| INVALID_ESCAPE | 0x7E appears unescaped inside the frame body. |
| TRUNCATED | frame ends mid-escape, or shorter than the FCS. |
Use @serialpilot/parser-hdlc if you want a Transform stream that emits one unframed payload per 0x7E boundary.
License
MIT.
