Skip to content

Protocol

The protocol is designed to be:

  • Easy to use and understand
  • Efficient to read and build
  • Lightweight to store and transmit
  • Usable in a variety of settings, without complex or bloated dependencies

Byte Breakdown

In a byte stream, you may receive a series of messages.

The makeup of a message is as follows (including options prefix) is as follows:

[optional prefix] <message>

<message> ::=       <version:uint8> <length:uint16> <type:uint16>
                    <header-data> <payload-data> <checksum:uint16>

<header-data> ::=   <data>
<payload-data> ::=  <data>

<data> ::=  <field-count:uint16> <fields:[]uint8> <data:[]bBytes>

ℹ️ Information

All integers are in little-endian format eg. (uint16 1 is represented as 0x01 0x00).

As an example empty message including prefix (with no additional header or payload data):

Example Message

An example prefixed and minimal message might look as follows:

FormatMessage
Bytes76 66 3 11 0 1 0 0 0 0 0 75 190
Hex4c 42 03 0b 00 01 00 00 00 00 00 4b be

ℹ️ Information

All integers are in little-endian format eg. (uint16 1 is represented as 0x01 0x00).

The general structure of a message is as follows:

Byte positionDescriptionTypeExample
1Protocol Version (always 3)uint83
2 -> 3Message Lengthuint1611 0
4 -> 5Message Typeuint161 0
6 -> aHeader Data (field count, fields, data)uint16, []uint8, []bBytes0 0
a -> bPayload Data (field count, fields, data)uint16, []uint8, []bBytes0 0
b -> nChecksumuint1675 190

So the full above example would be: