COMMS
Template library intended to help with implementation of communication protocols.
|
The COMMS library provides default comms::protocol::MsgIdLayer protocol stack layer to manage message ID information in the protocol framing. However, it may be insufficient (or incorrect) for some particular use cases, such as using bitfield field to store both numeric message ID and some extra flags (like MQTT protocol does). The Implementing New Layers section of the Protocol Stack Definition Tutorial page explains how to define new (custom) protocol layer.
NOTE, that comms::protocol::MsgIdLayer class contains significant amount of compile time logic of choosing the best code based on provided options as well as available polymorphic interface messages being read and/or written. It is very impractical to try to implement something similar from scratch or copy-paste the existing definition and introduce required changes.
Since v1.2 COMMS library provides an ability to extend the existing definition of comms::protocol::MsgIdLayer and customize some bits and pieces. Let's implement the mentioned example of sharing the same byte for numeric ID and some flags.
First of all let's define the Common Interface Class, which holds the flags information as data member of every message object.
Just to refresh the reader's memory: the usage of COMMS_MSG_TRANSPORT_FIELDS_NAMES() macro for the interface definition will generate transportField_flags() convenience member function to access the stored flags field, while usage of COMMS_BITMASK_BITS_SEQ() in the flags field definition will genereate getBitValue_X() and setBitValue_X() convenience member functions to get / set values of the bits (where X is one of the defined names: bit0, bit1, bit2, and bit3).
Now, let's define the bitfield field, that splits one byte in half to store numeric message ID (in lower 4 bits) as well as extra flags (in upper 4 bits)
Again, just to refresh the reader's memory: the usage of COMMS_FIELD_MEMBERS_NAMES() macro for the bitfield definition will generate field_X() convenience access member functions for the listed names.
Now it's time to actually extend the provided definition of the comms::protocol::MsgIdLayer and support usage of the defined earlier IdAndFlagsField field.
The comms::protocol::MsgIdLayer doesn't have any virtual functions and as the result not able to provide any polymorphic behavior. In order to be able to extend its default functionality there is a need to use Curiously Recurring Template Pattern. It is done by passing comms::option::def::ExtendingClass extension option with the type of the layer class being defined to the comms::protocol::MsgIdLayer.
The extending class can customize the default behavior by overriding the listed below functions. They do not necessarily need to be static, accessing inner private state of the layer object is also acceptable.
The newly defined custom protocol stack layer can be used instead of comms::protocol::MsgIdLayer when defining protocol stack (framing) of the protocol.