Expand description
Binary encoding for structured data communication.
This module provides a complete protocol implementation featuring:
- COBS framing via
cobsin- in-place encoding, eliminates delimiter issues in binary data - CRC-16 error detection via
crc- catches transmission errors - postcard serialization - compact no_std serde format
§Protocol Stack
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Application │ -> │ postcard │ -> │ + CRC-16 │ -> │ COBS │ -> Transport
│ Structs │ │ Serialize │ │ (appended) │ │ Framing │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Transport -> ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ COBS │ -> │ CRC-16 │ -> │ postcard │ -> │ Application │
│ Unframing │ │ Verify │ │ Deserialize│ │ Structs │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘§Packet Format
┌───────────────────────────────────────────────┬────────┐
│ COBS Encoded: {postcard_payload, crc16_le} │ 0x00 │
│ │ (COBS │
│ │ marker)│
└───────────────────────────────────────────────┴────────┘The protocol is optimized for minimal overhead:
- User data is serialized once with postcard
- CRC-16 is appended directly (no double serialization)
- The combined payload is COBS-encoded to eliminate zero bytes
§Example Usage
use pcobs::{serialize, deserialize};
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
struct SensorData {
sensor_id: u32,
value: u16,
timestamp: u64,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a message
let msg = SensorData {
sensor_id: 0,
value: 2345,
timestamp: 12345,
};
// Encode for transmission
let mut buf = [0u8; 512];
let len = serialize(&msg, &mut buf)?;
// In a real scenario, send buf[..len] over transport, followed by 0x00
// Decode received data (after accumulating until 0x00)
let decoded: SensorData = deserialize(&mut buf, len)?;
assert_eq!(msg, decoded);
Ok(())
}§Buffer Size Requirements
Encoding is done in-place - no buffer splitting needed. COBS adds minimal overhead (at most 1 byte per 254 bytes of input), plus 2 bytes for CRC-16.
For example, a 512-byte buffer can handle payloads up to ~508 bytes.
§Transport Agnostic
This protocol is transport-agnostic and can be used over any byte stream:
- UART/Serial
- TCP sockets
- USB bulk endpoints
- Radio protocols
- File I/O for testing
Enums§
- Decode
Error - Error during decoding (deserialization).
- Encode
Error - Error during encoding (serialization).
Functions§
- deserialize
- Decodes a complete packet with CRC inside COBS framing.
- serialize
- Encodes a complete packet with CRC inside COBS framing.