Protocol Versioning Summary
This chapter summarizes all version related aspects of the protocol definition.
Version of the Schema
<?xml version="1.0" encoding="UTF-8"?> <schema name="MyProtocol" version="5"> ... </schema>
Version in the Interface
If protocol reports its version via transport framing or via some special "connection" message, and the protocol version must influence how some messages are deserialized / handled, then there is a need for <interface> definition, which must contain version field, marked as such using semanticType="version" property.
<?xml version="1.0" encoding="UTF-8"?> <schema name="MyProtocol" version="5"> <interface name="Interface"> <int field="SomeName" type="uint16" semanticType="version" /> </interface> ... </schema>
Version in the Frame
In addition to the <interface> containing version information, the transport <frame> is also expected to contain <value> layer, which will reassign the received version information to the message object (via <interface>).
<?xml version="1.0" encoding="UTF-8"?> <schema name="MyProtocol" version="5"> <interface name="Interface"> <int field="SomeName" type="uint16" semanticType="version" /> </interface> <frame name="Frame"> <size name="Size"> <int name="SizeField" type="uint16" serOffset="2"/> </size> <id name="Id"> <int name="IdField" type="uint8" /> </id> <value name="Version" interfaces="Interface" interfaceFieldName="SomeName"> <int name="VersionField" type="uint16" /> </value> <payload name="Data" /> </frame> </schema>
Version of the Fields and Messages
- sinceVersion - Version when the message / field has been introduced.
- deprecated - Version when the message / field has been deprecated.
- removed - Indication that deprecated message / field must be removed from serialization and code generation.
Version Dependency of the Code
The generated code is expected to be version dependent (i.e. presence of some messages / fields is determined by the reported version value), if at least one of the defined <interface>-es contains version field (marked by semanticType="version").
If none of the interfaces has such field, then the generated code cannot be version dependent and all the version related properties become for documentation purposes only and cannot influence the presence of the messages / fields. In such cases the code generator is expected to receive required protocol version in its command line parameters and generate code for requested protocol version.
In case CommsDSL is used to define new protocol developed from scratch and backward / forward compatibility of the protocol is a desired feature, then there are few simple rules below, following of which can insure such compatibility.
- Use <size> layer in the transport framing to report remaining length of the message.
- Use <value> layer to report protocol version in the transport framing or define special "connect" message that is sent to establish connection and report protocol version (mark the <value> layer to be pseudo).
- Always add new fields at the end of the <message>. Don't forget to specify their version using sinceVersion property.
- Don't remove deprecated fields.
- Always add new fields at the bottom of the <list> element.
- Add element serialization length report before every element of the <list> field (done using elemLengthPrefix property).
- In case elemFixedLength property is assigned for the <list> (to avoid redundant report of the same element length before every element), never add variable length fields to the element of the list.