Wiki

Clone wiki

RVR CPP / Host Layer

Host Layer


The host layer describes how the two systems successfully exchange a payload of data. At this layer the content in the payload is immaterial.

Packet

The topmost layer is the packet. This is a string of bytes that is readily identified and extracted from a longer stream of bytes. A packet frequently is identified by specific bytes that indicate its beginning and end.

Error Detection

The host layer is also responsible for detecting errors in the transfer of a packet. The RVR uses a simple sum of the payload for error detection.

Packet Layout

An RVR host layer packet consists of:

<SOP><payload><sum><EOP> 

With the following meanings and byte definitions for the RVR:

Byte Meaning
SOP start of packet
EOP end of packet
payload information being transferred
sum inverted summation of the payload bytes

Where sum is calculated by:

#!c++

    using MsgArray = std::vector<uint8_t>;

    MsgArray payload;
      for (auto d : payload) {
         sum += d;
         }
    sum = ( ~sum & 0xFF);
The sum is inverted at the end to allow the use of the same code to check for errors. The sum for the received data, including the sum, is zero if there are no errors. This is a typical implementation detail for protocol error checking. Using a simple sum for error checking is not entirely robust. There are many errors that can occur which this check will not detect.

Byte Escaping

A payload byte may contain any value which includes the values for SOP and EOP. To address this situation the special values used by the protocol are escaped. This is analogous to the use of the \ in a string to indicate \n is the linefeed character, not the character n.

The RVR uses these characters to handle escaping:

Meaning Value
SOP 0x8D
EOP 0xD8
ESC 0xAB
escaped_SOP 0x05
escaped_EOP 0x50
escaped_ESC 0x23

After the sum is appended to the payload, since its value could require escaping, the payload bytes are scanned for occurences of the SOP, EOP, and ESC values. Each occurrence is replaced by the ESC byte and the escaped equivalent value. For example, an SOP is replaced with ESC escaped_SOP.

A code snippet for this is:

#!cpp
    using MsgArray = std::vector<uint8_t>;

       auto Packet::escape_char(MsgArray::iterator& p, MsgArray& payload) {

        switch ( *p) {
            case SOP: {
                *p = ESC;
                payload.insert(p + 1, escaped_SOP);
                break;
            }
            case EOP: {
                *p = ESC;
                payload.insert(p + 1, escaped_EOP);
                break;
            }
            case ESC: {
                *p = ESC;
                payload.insert(p + 1, escaped_ESC);
                break;
            }
        }
        ++p;
        return p;
    }

A received packet is subjected to the reverse operation which returns escaped sequences to original values.

Updated