Skip to main content

Transport Layer Description

Message Structure

The transport layer protocol is encapsulated by Start of Transmission (STX = 0x02) and End of Transmission (ETX = 0x03) characters.

All other characters at the transport layer will be printable ASCII characters in the range ‘0’-‘9’ and ‘A’-F’. This implies that the reception of STX or ETX has an unambiguous meaning – they always indicate the start or end of a message.

The protocol data and CRC data are encoded as hex strings. This means a single byte is sent as 2 characters in ASCII, in the order high nibble then low nibble. For example, the value 0x2A will be sent as ASCII chars ‘2’, ‘A’, which is equivalent to 0x32, 0x41 in hex.

Uppercase letters are used for the hex representations of A-F. If lowercase letters are received (a-f), they will be converted to uppercase A-F.

A CRC is computed over the protocol data. The CRC is computed over the data before encoding into the hex string form (i.e. compute the CRC before encoding into ASCII). The STX and ETX are not included in the CRC calculation. See the CRC section for more detail on the CRC.

The table below shows the message structure:

Start (STX)Protocol DataCRC1 High NibbleCRC1 Low NibbleCRC2 High NibbleCRC2 Low NibbleStop (ETX)
0x02Protocol Data, as hex string, where each protocol byte is encoded to 2 characters for transport1 byte, '0'-'9', 'A'-'F'1 byte, '0'-'9', 'A'-'F'1 byte, '0'-'9', 'A'-'F'1 byte, '0'-'9', 'A'-'F'0x03
Only Protocol Data (before ASCII encoding) is included in CRC calculation

To illustrate this, consider the Configuration Write Request:

  • Application layer: the message is simply the operation code (0x05) followed by 3 bytes of parameters (0x05, 0x00, 0x01). The result is [0x05, 0x05, 0x00, 0x01]
  • Transport layer:
    • Compute the CRC as 0x54C3 and append it: [0x05, 0x05, 0x00, 0x01, 0x54, 0xC3]
    • Encode as hex string: [0x30, 0x35, 0x30, 0x35, 0x30, 0x30, 0x30, 0x31, 0x35, 0x34, 0x43, 0x33]
    • Add STX and ETX, which gives the result to be sent over the UART: [0x02, 0x30, 0x35, 0x30, 0x35, 0x30, 0x30, 0x30, 0x31, 0x35, 0x34, 0x43, 0x33, 0x03]

Hex String Examples

All data in the protocol is converted to hex strings for transport. This can be illustrated with some examples.

First, consider that the same data can have a variety of representations. We will work in the hex notation.

For example, the ASCII string Hello World! can be represented as a hex array 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x21. We will work with our data as bytes or collections of bytes with a value 0x00 to 0xFF.

This hex data is encoded as high and low nibbles. Take the first character H above, which is 0x48. This is encoded to 0x34 (‘4’) and 0x38 (‘8’), So our example array becomes:

Hello‘ ‘world!

The last row of the table shows the bytes sent over the serial link.

Request / Answer

The application protocol uses a request/answer mechanism, where all requests are initiated by the asset.


The asset should wait for an answer to each request before sending another request.

Transport Layer Timing and Timeouts

Answers to requests can be expected to be received within 100 ms after reception of the last byte of the request. Past that delay, the asset can consider that a transmission error has occurred, and the asset should retry.


There are 2 exceptions: the configuration save request (CFG_SR) and configuration factor reset (CFG_FR) may take up to 1.5 sec to reply.

A 100ms inter-byte timeout is implemented on the module to recover from incomplete requests. Within a single message, bytes should not be spaced by more than 100ms. With more than 100 ms between bytes, the module will discard the in-progress receive operation and wait for the next start byte.


The CRC bytes allow the integrity of the message to be checked.

The CRC is calculated over all bytes from the application layer before the hex string encoding. The Start (STX) and End (ETX) bytes are excluded from the CRC calculation.

The result is 2 bytes, which are appended to the application layer data as the high then the low byte. The application layer data with CRC should then be encoded to the hex string form.

A CRC-16-CCITT checksum is used, defined by the polynomial x16+x12+x5+1, or 0x1021. The syndrome is initialised to 0xFFFF at the start. This is used in protocols such as Bluetooth.

Example of Implementation

// Computes the CRC-CCITT
// data The buffer containing the data bytes.
// dataLength The number of bytes to read from the buffer.
// init Initial syndrome value.

uint16_t crc_compute(const uint8_t* data, uint16_t data_length)
uint16_t x = 0;
uint16_t crc = 0xFFFF;

while (data_length--)
x = crc >> 8 ^ *data++;
x ^= x >> 4;
crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ (x);
return crc;

Verification Examples

00 001D 0F
00 00 00CC 9C
AB CD EF 0104 A2
14 56 F8 9A 00 017F D5