Message: Create a type system so non-frame data can be represented

This change breaks existing code, hence the version bump, but it's
going to be much less error prone going forward.
This commit is contained in:
Paul Hollinsky
2021-05-22 01:58:36 -04:00
parent 21e93d1f73
commit 21bc4eeff2
48 changed files with 853 additions and 527 deletions
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stddef.h>
#include "icsneo/communication/network.h"
#include "icsneo/communication/message/message.h"
#pragma pack(push, 1)
@@ -18,12 +19,12 @@ typedef union {
uint32_t extendedFrame : 1;
uint32_t remoteFrame : 1;
uint32_t crcError : 1;
uint32_t canErrorPassive : 1;
uint32_t canErrorPassive : 1; // Occupies the same space as headerCRCError
uint32_t incompleteFrame : 1;
uint32_t lostArbitration : 1;
uint32_t undefinedError : 1;
uint32_t canBusOff : 1;
uint32_t canErrorWarning : 1;
uint32_t canBusRecovered : 1;
uint32_t canBusShortedPlus : 1;
uint32_t canBusShortedGround : 1;
uint32_t checksumError : 1;
@@ -101,24 +102,34 @@ typedef union {
#endif
typedef struct {
neomessage_statusbitfield_t status;
uint8_t _reserved1[16];
uint64_t timestamp;
uint64_t timestampReserved;
const uint8_t* data;
size_t length;
uint8_t header[4];
neonetid_t netid;
neonettype_t type;
uint8_t reserved0;
uint16_t description;
uint8_t reserved1[14];
uint64_t _reservedTimestamp;
uint8_t _reserved2[sizeof(size_t) * 2 + 7 + sizeof(neonetid_t) + sizeof(neonettype_t)];
neomessagetype_t messageType;
uint8_t _reserved3[12];
} neomessage_t; // 72 bytes total
// Any time you add another neomessage_*_t type, make sure to add it to the static_asserts below!
typedef struct {
neomessage_statusbitfield_t status;
uint64_t timestamp;
uint64_t timestampReserved;
uint64_t _reservedTimestamp;
const uint8_t* data;
size_t length;
uint8_t header[4];
neonetid_t netid;
neonettype_t type;
uint8_t _reserved0;
uint16_t description;
neomessagetype_t messageType;
uint8_t _reserved1[12];
} neomessage_frame_t;
typedef struct {
neomessage_statusbitfield_t status;
uint64_t timestamp;
uint64_t _reservedTimestamp;
const uint8_t* data;
size_t length;
uint32_t arbid;
@@ -126,22 +137,38 @@ typedef struct {
neonettype_t type;
uint8_t dlcOnWire;
uint16_t description;
uint8_t reserved[14];
neomessagetype_t messageType;
uint8_t _reserved1[12];
} neomessage_can_t;
typedef struct {
neomessage_statusbitfield_t status;
uint64_t timestamp;
uint64_t timestampReserved;
uint64_t _reservedTimestamp;
size_t _reserved2[2];
uint8_t transmitErrorCount;
uint8_t receiveErrorCount;
uint8_t _reserved3[5];
neonetid_t netid;
neonettype_t type;
neomessagetype_t messageType;
uint8_t _reserved4[12];
} neomessage_can_error_t;
typedef struct {
neomessage_statusbitfield_t status;
uint64_t timestamp;
uint64_t _reservedTimestamp;
const uint8_t* data;
size_t length;
uint8_t preemptionFlags;
uint8_t reservedHeader[3];
uint8_t _reservedHeader[3];
neonetid_t netid;
neonettype_t type;
uint8_t reserved0;
uint8_t _reserved0;
uint16_t description;
uint8_t reserved1[14];
neomessagetype_t messageType;
uint8_t _reserved1[12];
} neomessage_eth_t;
#pragma pack(pop)
@@ -151,7 +178,9 @@ typedef struct {
#include <memory>
static_assert(sizeof(neomessage_t) == (56 + sizeof(void*) + sizeof(size_t)), "neomessage_t size is incorrect! Changing size will break compatibility with existing C API programs.");
static_assert(sizeof(neomessage_frame_t) == sizeof(neomessage_t), "All types of neomessage_t must be the same size! (Base frame is not)");
static_assert(sizeof(neomessage_can_t) == sizeof(neomessage_t), "All types of neomessage_t must be the same size! (CAN is not)");
static_assert(sizeof(neomessage_can_error_t) == sizeof(neomessage_t), "All types of neomessage_t must be the same size! (CAN error is not)");
static_assert(sizeof(neomessage_eth_t) == sizeof(neomessage_t), "All types of neomessage_t must be the same size! (Ethernet is not)");
namespace icsneo {