COBS Framer

Overview

Gantry makes use of Consistent Overhead Byte Stuffing (COBS) encoding for data sent or received. It allows from explicitly framed packets while keeping the worst-case packet size small.

The Gantry COBS framer provides helpers for decoding and encoding COBS data. The decoder can be used to convert an incoming data stream into discrete decoded frames. The encoder is used to encode a payload into a COBS frame in a single pass.

Usage

Decoding

Allocate a net_buf pool large enough for the largest expected payload. The max size is of the decoded payload, there is no need to include the overhead of COBS encoding and the data is decoded in place as it arrives.

Initialize a COBS frame decoder instance for your transport and provide it with the net_buff pool.

static struct cobs_frame_decoder decoder;

cobs_frame_decoder_init(&decoder, &rx_pool, on_frame, NULL);

Define a frame callback, then feed incoming bytes to the decoder as they arrive. The decoder fires the callback with a complete decoded frame once it sees the trailing COBS delimiter (0x00). The callback owns the net_buf and must call net_buf_unref when done.

static void on_frame(struct net_buf *buf, void *user_data)
{
   // Process the data
   net_buf_unref(buf);
}

void uart_rx_handler(const uint8_t *data, size_t len)
{
   cobs_frame_decoder_feed(&decoder, data, len);
}

Encoding

Allocate a net_buf pool large enough to hold the largest possible payload encoded using COBS. Use COBS_ENCODE_MAX_SIZE to calculate the worst-case encoded size.

To encode a net_buf using COBS, call cobs_frame_encode().

void send_data(struct net_buf *payload)
{
    struct net_buf *out = NULL;
    int ret = cobs_frame_encode(&tx_pool, payload, &out);
    // Free the original net_buf
    net_buf_unref(payload);

    if (ret == 0) {
      // Transmit the data...

      // Free the encoded net_buf
      net_buf_unref(out);
    }
}

Configuration

# Enable the COBS framer module
GANTRY_COBS_FRAMER=y

API Reference

typedef void (*cobs_frame_cb_t)(struct net_buf *buf, void *user_data)

Callback invoked when a complete COBS frame has been decoded.

The callback receives ownership of buf. The consumer must call net_buf_unref(buf) when done with it.

Param buf:

Decoded payload

Param user_data:

Opaque pointer supplied to cobs_frame_decoder_init

int cobs_frame_decoder_init(struct cobs_frame_decoder *frame_decoder, struct net_buf_pool *pool, cobs_frame_cb_t cb, void *user_data)

Initialise a COBS frame decoder instance.

Allocates the first receive net_buf from pool. Must be called before cobs_frame_decoder_feed.

Parameters:
  • frame_decoder – Frame decoder instance to initialise

  • pool – net_buf pool used for decoded frame buffers

  • cb – Called when the decoder receives a complete COBS frame

  • user_data – User data forwarded to the callback

Returns:

0 on success

Returns:

-EINVAL if any pointer argument is NULL

Returns:

-ENOMEM if the initial net_buf cannot be allocated from pool

int cobs_frame_decoder_feed(struct cobs_frame_decoder *frame_decoder, const uint8_t *data, size_t len)

Feed bytes into the COBS frame decoder.

The frame decoder callback is called when a complete frame is received. Frames that overflow the pool buffer size are dropped.

Parameters:
  • frame_decoder – Frame decoder instance

  • data – Byte(s) to process

  • len – Number of bytes in data

Returns:

0 on success

Returns:

-ENOMEM if a replacement net_buf cannot be allocated after a complete frame; the framer is unable to receive further frames until a buffer becomes available

int cobs_frame_encode(struct net_buf_pool *pool, const struct net_buf *input, struct net_buf **output)

COBS-encode a net_buf payload into a newly allocated net_buf.

Allocates an output net_buf from pool, performs a single encoding pass, and returns it via output.

The input net_buf is not modified and its reference count is not changed. The caller owns *output and must call net_buf_unref after transmission.

Parameters:
  • pool – Pool from which the encoded output net_buf is allocated

  • input – net_buf containing the payload to encode

  • output – a net_buf containing the encoded output

Returns:

0 on success

Returns:

-EINVAL if any pointer argument is NULL

Returns:

-ENOMEM if the output net_buf cannot be allocated from pool

Returns:

-ENOSPC if the allocated net_buf is too small for the encoded output

COBS_ENCODE_MAX_SIZE(src_len)

Helper for calculating the worst-case size of data encoded in a CBOR frame.

struct cobs_frame_decoder
#include <cobs_framer.h>

State for a COBS frame decoder instance.

Initialise with cobs_frame_decoder_init before use.