Routing Interface
Router
The Router reads PDUs from readers, and writes them to the appropriate writers.
It is configured using a routing table which describes where the PDUs should be routed and with which message ID. This table is described in the detailed design, and can be produced using the blob configuration that is generated from a high-level jsonl description using the generation tools.
Properties
Given N the number of known PDUs, and M the number of channels, the memory usage range, in bytes, is given by the following formula:
where the lower bound corresponds to PDUs with no destinations, and the upper bound corresponds to every PDU being routed to every channel.
For example, for 10 known PDUs and 3 channels, the memory usage will be in the range \([44, 194]\) bytes.
Template Parameters
* \tparam MAX_NUM_CHANNELS The maximum number of channels to write to and from. Needs to fit the
Public API
/**
* Construct an uninitialized Router.
*/
Router() = default;
/**
* Initialize a Router using a pre-filled PduRoutingTable.
*
* It starts with transmission and reception enabled for all channels.
*/
void init(
::routing::PduRoutingTable const& table,
::etl::span<::io::IReader*> readers,
::etl::span<::io::IWriter*> writers);
/**
* Initialize a Router by loading the PduRoutingTable from the provided config byte array.
*
* If the config data is invalid, the Router will be uninitialized and the other functions will
* not do anything apart from logging an error.
*
* Otherwise, it starts with transmission and reception enabled for all channels.
*/
void init(
::etl::span<uint8_t const> config,
::etl::span<::io::IReader*> readers,
::etl::span<::io::IWriter*> writers);
/**
* Try routing a PDU from a channel.
*
* It returns true once a PDU is routed. Otherwise, it returns false after attempting once from
* each channel.
*/
bool run();
RxAdapter
The RxAdapter is an adapter that extracts PDUs from messages in the provided IReader, exposing them with the IReader interface. It counts the PDUs and bytes extracted from the messages.
Its configuration is also achieved using an appropriate table.
Properties
Given N the number of known PDUs, M the number of channels, L the number of messages with explicit configured lengths, and P the number of known messages, the total memory usage of all adapters, in bytes, is given by the following formula:
For example, for 10 known PDUs, 3 channels, 5 known messages, and 2 configured message lengths, the memory usage will be 152 bytes.
Template Parameters
* \tparam MAX_ELEMENT_SIZE The maximum size of an extracted PDU.
* \tparam MAX_ELEMENT_SIZE The maximum size of an extracted PDU.
Public API
/**
* Construct an RxAdapter with a pre-filled RxAdapterTable.
*/
RxAdapter(
::io::IReader& inputReader,
::etl::span<uint8_t> buffer,
RxAdapterTable const& table,
ErrorHandler errorHandler);
/**
* Return the size of the buffer.
*/
size_t maxSize() const override;
/**
* Each peek() call following a release() call will return the next PDU extracted from the
* current message of the IReader, according to the list defined in the RxAdapterTable.
* Once all the PDUs have been read, or if the current message is not known in the table, a new
* peek() call will be performed on the IReader, releasing the previous one.
*
* An empty span will be returned if nothing is available.
*/
::etl::span<uint8_t> peek() const override;
/**
* Reset the internal PDU buffer, allowing the next peek() call to extract a new PDU from a
* message.
*/
void release() override;
// The PDU and byte counters keep track of the total amount of data read from the input queue,
// regardless of the number of PDUs extracted.
StatCounter::Type pduCounter() const { return _pduCounter; }
StatCounter::Type byteCounter() const { return _byteCounter; }
// The discarded PDU and byte counters store the amount of data in incoming messages out of
// which not a single PDU was extracted.
StatCounter::Type invalidHeaderSizePdus() const { return _invalidHeaderSizePdus; }
StatCounter::Type unknownMessagePdus() const { return _unknownMessagePdus; }
StatCounter::Type invalidParsedPayloadLengthPdus() const
{
return _invalidParsedPayloadLengthPdus;
}
StatCounter::Type invalidPayloadLengthPdus() const { return _invalidPayloadLengthPdus; }
StatCounter::Type discardedPduCounter() const { return _discardedPduCounter; }
StatCounter::Type discardedByteCounter() const { return _discardedByteCounter; }
/**
* Construct a PduTransportRxAdapter with a pre-filled RxAdapterTable.
*/
PduTransportRxAdapter(
::io::IReader& inputReader, RxAdapterTable const& table, ErrorHandler errorHandler);
/**
* Return the MAX_ELEMENT_SIZE
*/
size_t maxSize() const override;
::etl::span<uint8_t> peek() const override;
// The discarded PDU and byte counters store the amount of data in incoming messages out of
// which not a single PDU was extracted.
StatCounter::Type invalidMessageLengthPdus() const { return _invalidMessageLengthPdus; }
/**
* Construct an LegacyRxAdapter with a pre-filled RxAdapterTable.
*/
LegacyRxAdapter(
::io::IReader& inputReader, RxAdapterTable const& table, ErrorHandler errorHandler);
/**
* Return the MAX_ELEMENT_SIZE
*/
size_t maxSize() const override;
PduTransportTxAdapter
The PduTransportTxAdapter is an adapter that forwards PDUs to an IWriter, exposing an IWriter interface itself. It collects statistics about the size and number of PDUs forwarded.
Public API
/**
* All the methds delegate to the underlying IWriter, while counting the bytes.
*/
PduTransportTxAdapter(::io::IWriter& outputWriter, ErrorHandler errorHandler);
size_t maxSize() const override;
::etl::span<uint8_t> allocate(size_t size) override;
void commit() override;
void flush() override;
// The PDU and byte counters keep track of the total amount of data written to the output queue.
StatCounter::Type pduCounter() const { return _pduCounter; }
StatCounter::Type byteCounter() const { return _byteCounter; }
// The dropped PDU and byte counters store the amount of data that was not transmitted
// because the output queue was full.
StatCounter::Type failedMemAllocPdus() const { return _failedMemAllocPdus; }
StatCounter::Type droppedPduCounter() const { return _droppedPduCounter; }
StatCounter::Type droppedByteCounter() const { return _droppedByteCounter; }
LegacyTxAdapter
The LegacyTxAdapter is an adapter that forwards PDUs to an IWriter, exposing an IWriter interface itself. It is meant to be used for legacy buses, like CAN or FlexRay, where the incoming PDU needs to be sent in a specific position in an outgoing PDU.
Its configuration is achieved using an appropriate table.
Public API
/**
* Construct a LegacyTxAdapter from a pre-filled TxAdapterTable.
*/
LegacyTxAdapter(
::io::IWriter& outputWriter,
::routing::TxAdapterTable const& table,
ErrorHandler errorHandler);
/**
* Return the maxSize() of the underlying writer.
*/
size_t maxSize() const override;
/**
* Try to allocate max_size() of the underlying writer, and return a subspan of this memory.
* This will fail if there is not at least max_size() available in the underlying writer.
*/
::etl::span<uint8_t> allocate(size_t size) override;
/**
* Find the correct message in the table, allocate, move the buffered PDU in the
* correct place, and fill the rest with 0xFF.
*/
void commit() override;
/**
* Call flush on the underlying IWriter.
*/
void flush() override;
// The PDU and byte counters keep track of the total amount of data written to the output queue.
StatCounter::Type pduCounter() const { return _pduCounter; }
StatCounter::Type byteCounter() const { return _byteCounter; }
// The dropped PDU and byte counters store the amount of data that was not transmitted
// because allocation or commit failed. This occurs when the output queue is full, output
// message ID is unknown or PDU offset is invalid.
StatCounter::Type oversizedPdus() const { return _oversizedPdus; }
StatCounter::Type failedMemAllocPdus() const { return _failedMemAllocPdus; }
StatCounter::Type unknownMessagePdus() const { return _unknownMessagePdus; }
StatCounter::Type failedMemMovePdus() const { return _failedMemMovePdus; }
StatCounter::Type droppedPduCounter() const { return _droppedPduCounter; }
StatCounter::Type droppedByteCounter() const { return _droppedByteCounter; }