Packet Structure

Every CONDUYT packet follows a fixed 8-byte header plus variable-length payload.

Frame Layout

[0-1]   MAGIC   0x43 0x44
[2]     VER     0x02
[3]     TYPE    command or event byte
[4]     SEQ     0-255 rolling
[5-6]   LEN     payload length, little-endian uint16
[7..N]  PAYLOAD variable length
[7+N]   CRC8    over bytes [2..6+N]

Total overhead: 8 bytes (MAGIC(2) + VER(1) + TYPE(1) + SEQ(1) + LEN(2) + CRC8(1)).

Notation

The following type notation is used throughout the reference docs:

SymbolMeaning
u8Unsigned 8-bit integer (1 byte)
u16Unsigned 16-bit integer (2 bytes, little-endian)
i32Signed 32-bit integer (4 bytes, little-endian)
f3232-bit IEEE 754 float (4 bytes, little-endian)
NVariable length (remaining bytes in payload)
LELittle-endian byte order

All multi-byte integers are transmitted least-significant byte first (little-endian).

Field Definitions

FieldSizeDescription
MAGIC2 bytes0x43 0x44 ("CD"). Catches misaligned reads on serial streams.
VER1 byteProtocol version. Currently 0x02. v0.1 (0x01) shipped a corrupted CRC8 lookup table at indices 0xE0..0xFF; v0.2 ships the canonical table generated from the polynomial. v0.2 hosts must reject v0.1 packets — re-flash old firmware.
TYPE1 byteCommand (host to device) or event (device to host) type. See Packet Types.
SEQ1 byteRolling sequence 0 to 255. Host increments per command. Device echoes in response.
LEN2 bytesPayload length, little-endian uint16. Max capped at device's max_payload.
PAYLOADN bytesType-specific data. Zero-length for PING, RESET, etc.
CRC81 byteCRC8 over bytes from VER through end of PAYLOAD: crc8(buf[2..7+payloadLen]).

Worked Example

A PIN_WRITE packet (type 0x11) that sets pin 13 to HIGH:

43 44 02 11 01 02 00 0D 01 XX

Byte-by-byte breakdown:

OffsetBytesFieldValue
0-143 44MAGIC"CD"
202VERProtocol version 2
311TYPEPIN_WRITE (0x11)
401SEQSequence number 1
5-602 00LEN2 bytes payload (little-endian)
70DPAYLOAD0Pin 13
801PAYLOAD1Value 1 (HIGH)
9XXCRC8CRC8 over bytes 2-8: [02 11 01 02 00 0D 01]

The CRC8 is computed using Dallas/Maxim polynomial 0x31 over VER through end of PAYLOAD (7 bytes in this case). XX represents the computed checksum.

Total: 10 bytes on the wire (8 header + 2 payload). On serial transports, COBS framing adds 1-2 bytes of overhead plus a 0x00 delimiter byte.

CRC8

The checksum covers VER(1) + TYPE(1) + SEQ(1) + LEN(2) + PAYLOAD(N). That is, bytes [2..6+N] in the packet buffer.

  • Polynomial: Dallas/Maxim 0x31
  • Init value: 0x00
  • Input/output reflection: none
uint8_t crc8(const uint8_t *data, size_t len) {
    uint8_t crc = 0x00;
    for (size_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (uint8_t bit = 0; bit < 8; bit++) {
            crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
        }
    }
    return crc;
}

COBS Framing

Serial and BLE transports wrap each packet in COBS (Consistent Overhead Byte Stuffing) encoding before transmission. COBS eliminates 0x00 from the encoded data, so 0x00 serves as a reliable packet delimiter.

  • Overhead: 1 byte per 254 bytes of data
  • Delimiter: 0x00 after each COBS-encoded packet

TCP, WebSocket, and MQTT transports skip COBS. TCP uses length-prefixed reads, and MQTT delivers discrete messages with built-in framing.

TransportCOBS
Serial (UART/USB)Yes
USB CDCYes
BLEYes
CLASPYes
TCPNo
WebSocketNo
MQTTNo