19                           const std::uint8_t *dataBuffer,
 
   21                           std::shared_ptr<ControlFunction> source,
 
   22                           std::shared_ptr<ControlFunction> destination,
 
   23                           std::uint8_t CANPort) :
 
   25      identifier(identifier),
 
   26      data(dataBuffer, dataBuffer + length),
 
   28      destination(destination),
 
 
   35                           std::vector<std::uint8_t> data,
 
   36                           std::shared_ptr<ControlFunction> source,
 
   37                           std::shared_ptr<ControlFunction> destination,
 
   38                           std::uint8_t CANPort) :
 
   40      identifier(identifier),
 
   41      data(std::move(data)),
 
   43      destination(destination),
 
 
   75        return (
nullptr != 
source) && 
source->get_address_valid();
 
 
  126        assert(
nullptr != dataBuffer && 
"CANMessage::set_data() called with nullptr dataBuffer");
 
  128        data.insert(
data.end(), dataBuffer, dataBuffer + length);
 
 
  133        assert(insertPosition <= 
ABSOLUTE_MAX_MESSAGE_LENGTH && 
"CANMessage::set_data() called with insertPosition greater than maximum supported");
 
  135        data[insertPosition] = dataByte;
 
 
  150        return data.at(index);
 
 
  155        return static_cast<std::int8_t
>(
data.at(index));
 
 
  160        std::uint16_t retVal;
 
  161        if (ByteFormat::LittleEndian == format)
 
  163            retVal = 
data.at(index);
 
  164            retVal |= 
static_cast<std::uint16_t
>(
data.at(index + 1)) << 8;
 
  168            retVal = 
static_cast<std::uint16_t
>(
data.at(index)) << 8;
 
  169            retVal |= 
data.at(index + 1);
 
 
  177        if (ByteFormat::LittleEndian == format)
 
  179            retVal = 
static_cast<std::int16_t
>(
data.at(index));
 
  180            retVal |= 
static_cast<std::int16_t
>(
data.at(index + 1)) << 8;
 
  184            retVal = 
static_cast<std::int16_t
>(
data.at(index)) << 8;
 
  185            retVal |= 
static_cast<std::int16_t
>(
data.at(index + 1));
 
 
  192        std::uint32_t retVal;
 
  193        if (ByteFormat::LittleEndian == format)
 
  195            retVal = 
data.at(index);
 
  196            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 1)) << 8;
 
  197            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 2)) << 16;
 
  201            retVal = 
static_cast<std::uint32_t
>(
data.at(index + 2)) << 16;
 
  202            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 1)) << 8;
 
  203            retVal |= 
data.at(index + 2);
 
 
  211        if (ByteFormat::LittleEndian == format)
 
  213            retVal = 
static_cast<std::int32_t
>(
data.at(index));
 
  214            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 1)) << 8;
 
  215            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 2)) << 16;
 
  219            retVal = 
static_cast<std::int32_t
>(
data.at(index + 2)) << 16;
 
  220            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 1)) << 8;
 
  221            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 2));
 
 
  228        std::uint32_t retVal;
 
  229        if (ByteFormat::LittleEndian == format)
 
  231            retVal = 
data.at(index);
 
  232            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 1)) << 8;
 
  233            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 2)) << 16;
 
  234            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 3)) << 24;
 
  238            retVal = 
static_cast<std::uint32_t
>(
data.at(index)) << 24;
 
  239            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 1)) << 16;
 
  240            retVal |= 
static_cast<std::uint32_t
>(
data.at(index + 2)) << 8;
 
  241            retVal |= 
data.at(index + 3);
 
 
  249        if (ByteFormat::LittleEndian == format)
 
  251            retVal = 
static_cast<std::int32_t
>(
data.at(index));
 
  252            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 1)) << 8;
 
  253            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 2)) << 16;
 
  254            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 3)) << 24;
 
  258            retVal = 
static_cast<std::int32_t
>(
data.at(index)) << 24;
 
  259            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 1)) << 16;
 
  260            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 2)) << 8;
 
  261            retVal |= 
static_cast<std::int32_t
>(
data.at(index + 3));
 
 
  268        std::uint64_t retVal;
 
  269        if (ByteFormat::LittleEndian == format)
 
  271            retVal = 
data.at(index);
 
  272            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 1)) << 8;
 
  273            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 2)) << 16;
 
  274            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 3)) << 24;
 
  275            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 4)) << 32;
 
  276            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 5)) << 40;
 
  277            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 6)) << 48;
 
  278            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 7)) << 56;
 
  282            retVal = 
static_cast<std::uint64_t
>(
data.at(index)) << 56;
 
  283            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 1)) << 48;
 
  284            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 2)) << 40;
 
  285            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 3)) << 32;
 
  286            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 4)) << 24;
 
  287            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 5)) << 16;
 
  288            retVal |= 
static_cast<std::uint64_t
>(
data.at(index + 6)) << 8;
 
  289            retVal |= 
data.at(index + 7);
 
 
  297        if (ByteFormat::LittleEndian == format)
 
  299            retVal = 
static_cast<std::int64_t
>(
data.at(index));
 
  300            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 1)) << 8;
 
  301            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 2)) << 16;
 
  302            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 3)) << 24;
 
  303            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 4)) << 32;
 
  304            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 5)) << 40;
 
  305            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 6)) << 48;
 
  306            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 7)) << 56;
 
  310            retVal = 
static_cast<std::int64_t
>(
data.at(index)) << 56;
 
  311            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 1)) << 48;
 
  312            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 2)) << 40;
 
  313            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 3)) << 32;
 
  314            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 4)) << 24;
 
  315            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 5)) << 16;
 
  316            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 6)) << 8;
 
  317            retVal |= 
static_cast<std::int64_t
>(
data.at(index + 7));
 
 
  324        assert(length <= 8 - bitIndex && 
"length must be less than or equal to 8 - bitIndex");
 
  325        std::uint8_t mask = ((1 << length) - 1) << bitIndex;
 
  326        return (get_uint8_at(byteIndex) & mask) == mask;
 
 
  331        std::uint64_t retVal = 0;
 
  332        std::uint8_t currentByte = 0;
 
  333        std::uint32_t endBitIndex = startBitIndex + length - 1;
 
  334        std::uint32_t bitCounter = 0;
 
  335        std::uint32_t amountOfBytesLeft = (length + 8 - 1) / 8;
 
  336        std::uint32_t startAmountOfBytes = amountOfBytesLeft;
 
  337        std::uint8_t indexOfFinalByteBit = 7;
 
  339        if (endBitIndex > 8 * 
data.size() || length < 1 || startBitIndex >= 8 * 
data.size())
 
  341            LOG_ERROR(
"End bit index is greater than length or startBitIndex is wrong or startBitIndex is greater than endBitIndex");
 
  345        for (
auto i = startBitIndex; i <= endBitIndex; i++)
 
  347            auto byteIndex = i / 8;
 
  348            auto bitIndexWithinByte = i % 8;
 
  349            auto bit = (
data.at(byteIndex) >> (indexOfFinalByteBit - bitIndexWithinByte)) & 1;
 
  350            if (length - bitCounter < 8)
 
  352                currentByte |= 
static_cast<uint8_t
>(bit) << (length - 1 - bitCounter);
 
  356                currentByte |= 
static_cast<uint8_t
>(bit) << (indexOfFinalByteBit - bitIndexWithinByte);
 
  359            if ((bitCounter + 1) % 8 == 0 || i == endBitIndex)
 
  361                if (ByteFormat::LittleEndian == format)
 
  363                    retVal |= (
static_cast<uint64_t
>(currentByte) << (startAmountOfBytes - amountOfBytesLeft) * 8);
 
  367                    retVal |= (
static_cast<uint64_t
>(currentByte) << ((amountOfBytesLeft * 8) - 8));
 
 
An abstraction of a CAN message, could be > 8 data bytes.
 
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
 
A utility class that allows easy interpretation of a 32 bit CAN identifier.
 
static constexpr std::uint32_t UNDEFINED_PARAMETER_GROUP_NUMBER
A fake PGN used internally to denote a NULL PGN.
 
std::uint32_t get_parameter_group_number() const
Returns the PGN encoded in the identifier.
 
static constexpr std::uint8_t GLOBAL_ADDRESS
The broadcast CAN address.
 
A class that represents a generic CAN message of arbitrary length.
 
std::int16_t get_int16_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 16-bit signed integer from the buffer at a specific index. A 16-bit signed integer can hold a v...
 
bool is_source(std::shared_ptr< ControlFunction > controlFunction) const
Returns whether the message is originated from the control function.
 
static const std::uint32_t ABSOLUTE_MAX_MESSAGE_LENGTH
ISO11783-3 defines this: The maximum number of packets that can be sent in a single connection with e...
 
std::shared_ptr< ControlFunction > source
The source control function of the message.
 
Type
The internal message type.
 
@ Receive
Message is being received.
 
bool is_destination(std::shared_ptr< ControlFunction > controlFunction) const
Returns whether the message is destined for the control function.
 
bool has_valid_destination_control_function() const
Returns whether the message is sent to a specific device on the bus.
 
std::int32_t get_int24_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a right-aligned 24-bit integer from the buffer (returned as a int32_t) at a specific index....
 
Type messageType
The internal message type associated with the message.
 
Type get_type() const
Returns the CAN message type.
 
static CANMessage create_invalid_message()
Factory method to construct an intentionally invalid CANMessage.
 
ByteFormat
The different byte formats that can be used when reading bytes from the buffer.
 
void set_data(const std::uint8_t *dataBuffer, std::uint32_t length)
Sets the message data to the value supplied. Creates a copy.
 
std::uint8_t get_can_port_index() const
Returns the CAN channel index associated with the message.
 
const std::vector< std::uint8_t > & get_data() const
Gets a reference to the data in the CAN message.
 
std::uint32_t get_data_length() const
Returns the length of the data in the CAN message.
 
bool has_valid_source_control_function() const
Returns whether the message is sent by a device that claimed its address on the bus.
 
void set_data_size(std::uint32_t length)
Sets the size of the data payload.
 
std::uint32_t get_uint24_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a right-aligned 24-bit integer from the buffer (returned as a uint32_t) at a specific index....
 
std::uint64_t get_data_custom_length(const std::uint32_t startBitIndex, const std::uint32_t length, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit unsinged integer from the buffer at a specific index but custom length Why 64 bit?...
 
CANIdentifier identifier
The CAN ID of the message.
 
std::shared_ptr< ControlFunction > get_source_control_function() const
Gets the source control function that the message is from.
 
std::uint8_t get_uint8_at(const std::uint32_t index) const
Get a 8-bit unsigned byte from the buffer at a specific index. A 8-bit unsigned byte can hold a value...
 
std::shared_ptr< ControlFunction > destination
The destination control function of the message.
 
bool is_parameter_group_number(CANLibParameterGroupNumber parameterGroupNumber) const
Compares the identifier of the message to the parameter group number (PGN) supplied.
 
std::vector< std::uint8_t > data
A data buffer for the message, used when not using data chunk callbacks.
 
void set_identifier(const CANIdentifier &value)
Sets the CAN ID of the message.
 
std::int32_t get_int32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit signed integer from the buffer at a specific index. A 32-bit signed integer can hold a v...
 
std::int8_t get_int8_at(const std::uint32_t index) const
Get a 8-bit signed byte from the buffer at a specific index. A 8-bit signed byte can hold a value bet...
 
std::uint16_t get_uint16_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 16-bit unsigned integer from the buffer at a specific index. A 16-bit unsigned integer can hold...
 
CANIdentifier get_identifier() const
Returns the identifier of the message.
 
std::int64_t get_int64_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit signed integer from the buffer at a specific index. A 64-bit signed integer can hold a v...
 
std::uint8_t CANPortIndex
The CAN channel index associated with the message.
 
bool get_bool_at(const std::uint32_t byteIndex, const std::uint8_t bitIndex, const std::uint8_t length=1) const
Get a bit-boolean from the buffer at a specific index.
 
std::uint32_t get_uint32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit unsigned integer from the buffer at a specific index. A 32-bit unsigned integer can hold...
 
CANMessage(Type type, CANIdentifier identifier, const std::uint8_t *dataBuffer, std::uint32_t length, std::shared_ptr< ControlFunction > source, std::shared_ptr< ControlFunction > destination, std::uint8_t CANPort)
Construct a CAN message from the parameters supplied.
 
std::shared_ptr< ControlFunction > get_destination_control_function() const
Gets the destination control function that the message is to.
 
bool is_broadcast() const
Returns whether the message is sent as a broadcast message / to all devices on the bus.
 
bool is_destination_our_device() const
Returns whether the message is destined for our device on the bus.
 
std::uint64_t get_uint64_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit unsigned integer from the buffer at a specific index. A 64-bit unsigned integer can hold...
 
@ Internal
The control function is part of our stack and can address claim.
 
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
 
CANLibParameterGroupNumber
PGNs commonly used by the CAN stack.