bacnet-mstp-codec
The MS/TP frame codec of
rusty-bacnet: the wire format
of Clause 9 of ASHRAE 135, and nothing above it. Token passing, timers and
line control belong to the layer that uses it, such as bacnet-mstp-core.
#![no_std], no allocator and no dependencies in the default build.- Standard frames and the two extended data frames (types 32 and 33), whose data goes on the wire COBS-encoded with a CRC-32K.
- The header CRC-8, the data CRC-16 and the CRC-32K, in the
crcmodule. - One-shot
Frame::encode_intoanddecode_frameover caller storage, anddecode_frame_in_placefor an extended frame, whose data is decoded over its encoded form. StreamDecoder, an incremental decoder for a serial byte stream, which keeps its receive state in a buffer you lend it, skips a frame too long for it by count, and reports every candidate it drops with the destination a receiver needs to judge it.FrameTypeis an open set: a constant for each type the standard defines, andfrom_rawfor any other octet, so a reserved or proprietary type passes through unchanged.- Decoding is a raw link-level check; encoding is strict. The crate docs list the checks in the order each direction runs them.
Features
None is on by default, and none needs std:
alloc: aFrameSinkforVec<u8>.bytes: aFrameSinkforbytes::BytesMut; impliesalloc.heapless: aFrameSinkforheapless::Vec<u8, N>.crc32k-table: works out the CRC-32K with a 256-entry table, about 1 KiB more flash than the default 16-entry one and half the lookups.
Example
use ;
// Encode a frame into caller storage, and decode it in one shot.
let frame = new;
let mut wire = ;
let length = frame.encode_into.unwrap;
assert_eq!;
// Or feed the octets to a stream decoder as a UART delivers them.
let mut storage = ;
let mut decoder = new;
let mut received = None;
for &octet in &wire
assert_eq!;
// Match frame types on their constants, with a `_` arm for the rest.
let kind = match from_raw ;
assert_eq!;
License
MIT