76 lines
4.0 KiB
Markdown
76 lines
4.0 KiB
Markdown
# Compatibility and Versioning
|
|
|
|
This document describes how bproto handles compatibility and versioning of protocols and messages.
|
|
|
|
When receiving a message, the receiver must know if the data is compatible with the hard-coded protocol implementation.
|
|
There are multiple mechanisms to ensure this.
|
|
|
|
The worst-case scenario is that the receiver gets a message that is not compatible with the protocol implementation -> meaning something has changed in the protocol and the receiver is not aware of it.
|
|
|
|
## Compatibility
|
|
|
|
**A protocol/message is compatible if**
|
|
- ✅ protocol and message definitions are the same
|
|
- ✅ the order of declaration of fields or messages has changed (but not the ID)
|
|
|
|
**A protocol/message is incompatible if**
|
|
- ❌ If the protocol version has changed
|
|
- ❌ If a message has been removed or added
|
|
- ❌ If the protocol, message, bitfield, enum, or field name has changed
|
|
- ❌ If Message or Field ID has changed
|
|
- ❌ the number, type, order, or array size of fields in a message has changed
|
|
- ❌ If the order of declaration of enums or bitfields has changed
|
|
|
|
=> In general, the receiver must have the same protocol implementation build as the sender.
|
|
|
|
## Naming Conventions
|
|
Use descriptive names that clearly indicate the purpose of the protocol. Avoid generic names. Also include a hint about the fact that this is for transmitting data like "protocol" or "datastream".
|
|
|
|
## Versioning Strategies
|
|
The version number is used to differentiate between different iterations of the protocol. Different versions of the same protocol are incompatible. By changing the protocol version, the developer can indicate a major change in structure, design, or purpose of the protocol/messages.Evalia
|
|
|
|
**Example:**
|
|
```bproto
|
|
protocol robotControlProtocol version 1
|
|
```
|
|
|
|
More about bproto's syntax can be found in the [syntax documentation](/docs/syntax.md#protocol-tag-line).
|
|
|
|
## Compatibility Validation Process in Detail
|
|
|
|
This is the message validation process that should prevent incompatible messages from being processed, causing undefined behavior.
|
|
|
|
**Step #1 - Message Size Check:**
|
|
The first byte of the message is the message ID.
|
|
The receiver can with the message ID derive the expected message size. (If the message ID is unknown, the size is set to 0)
|
|
The receiver can then check if the received message is of the expected size.
|
|
If the size is not as expected, the message is discarded.
|
|
-> This prevents messages with changed field/message sizes from being processed.
|
|
|
|
**Step #2 - CRC-16 Check:**
|
|
The CRC-16 is calculated over the message data and compared to the last 2 bytes of the message.
|
|
If the CRC-16 is not correct, the message is discarded.
|
|
|
|
The CRC-16 is initialized by first prepending a SHA-256 hash of a text form of the protocol definition to the message data.
|
|
This text form is a human-readable representation of the protocol definition but also represents the internal structure of the protocol used by the bproto-compiler to generate other protocol implementations.
|
|
If something changes in this internal structure, a potential incompatibility is introduced.
|
|
|
|
More details about how the CRC-16 is calculated can be found in the [serialization documentation](/docs/serialization.md#crc-16-calculation).
|
|
|
|
This text form can be generated by the bproto-compiler when choosing the backend "txt".
|
|
This will also display the CRC-16 initialization vector and SHA-256 hash of the protocol definition.
|
|
|
|
There are two possible reasons for a failed CRC check:
|
|
1. The message has been corrupted during transmission.
|
|
2. The message data is fine but the protocol definition has changed, and therefore the SHA-256 hash is different.
|
|
|
|
=> The CRC-16 protects against data corruption and protocol changes.
|
|
|
|
**Step #3 - Message ID Check:**
|
|
The receiver checks if the message ID is known.
|
|
If the message ID is unknown, the message is discarded.
|
|
|
|
After Step #2 the receiver should already have discarded the message if it is incompatible with the protocol implementation. Nevertheless, this step is an additional line of defense.
|
|
|
|
|