Skip to main content

Crate pcobs

Crate pcobs 

Source
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§

DecodeError
Error during decoding (deserialization).
EncodeError
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.