From 516bca682c06ea43c654af46befb3f456e68907d Mon Sep 17 00:00:00 2001 From: Thomas Stoddard Date: Wed, 7 Jan 2026 21:34:34 +0000 Subject: [PATCH] EthernetMessage: Add T1S symbol support --- communication/packet/ethernetpacket.cpp | 25 ++++++++++++++++--- .../communication/message/ethernetmessage.h | 20 ++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/communication/packet/ethernetpacket.cpp b/communication/packet/ethernetpacket.cpp index adf02ca..0c65d4a 100644 --- a/communication/packet/ethernetpacket.cpp +++ b/communication/packet/ethernetpacket.cpp @@ -1,5 +1,5 @@ #include "icsneo/communication/packet/ethernetpacket.h" -#include // for std::copy +#include #include using namespace icsneo; @@ -10,16 +10,17 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s // Make sure we have enough to read the packet length first if(bytestream.size() < sizeof(HardwareEthernetPacket)) return nullptr; - // packet->Length will also encompass the two uint16_t's at the end of the struct, make sure that at least they are here - if(packet->Length < 4) - return nullptr; const size_t fcsSize = packet->header.FCS_AVAIL ? 4 : 0; + // Ensure Length is sufficient for FCS extraction to avoid invalid iterator arithmetic + if(packet->Length < fcsSize) + return nullptr; const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + packet->Length; const size_t bytestreamActualSize = bytestream.size(); if(bytestreamActualSize < bytestreamExpectedSize) return nullptr; auto messagePtr = std::make_shared(); EthernetMessage& message = *messagePtr; + // Standard Ethernet fields message.transmitted = packet->eid.TXMSG; if(message.transmitted) message.description = packet->stats; @@ -27,12 +28,28 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s if(message.preemptionEnabled) message.preemptionFlags = (uint8_t)((rawWords[0] & 0x03F8) >> 4); message.frameTooShort = packet->header.RUNT_FRAME; + message.noPadding = !packet->header.ENABLE_PADDING; + message.fcsVerified = packet->header.FCS_VERIFIED; + message.txAborted = packet->eid.TXAborted; + message.crcError = packet->header.CRC_ERROR; + if(message.frameTooShort) message.error = true; // This timestamp is raw off the device (in timestampResolution increments) // Decoder will fix as it has information about the timestampResolution increments message.timestamp = packet->timestamp.TS; + // Check if this is a T1S packet and populate T1S-specific fields + message.isT1S = packet->header.T1S_ETHERNET; + if(message.isT1S) { + message.isT1SSymbol = packet->eid.T1S_SYMBOL; + message.isT1SBurst = packet->eid.T1S_BURST; + message.txCollision = packet->t1s_status.TXCollision; + message.isT1SWake = packet->t1s_status.T1SWake; + message.t1sNodeId = packet->t1s_node.T1S_NODE_ID; + message.t1sBurstCount = packet->t1s_node.T1S_BURST_COUNT; + } + const std::vector::const_iterator databegin = bytestream.begin() + sizeof(HardwareEthernetPacket); const std::vector::const_iterator dataend = databegin + packet->Length - fcsSize; message.data.insert(message.data.begin(), databegin, dataend); diff --git a/include/icsneo/communication/message/ethernetmessage.h b/include/icsneo/communication/message/ethernetmessage.h index d71d2d4..8d0f09f 100644 --- a/include/icsneo/communication/message/ethernetmessage.h +++ b/include/icsneo/communication/message/ethernetmessage.h @@ -4,17 +4,17 @@ #ifdef __cplusplus #include "icsneo/communication/message/message.h" - -// Used for MACAddress.toString() only +#include +#include #include #include +#include namespace icsneo { struct MACAddress { uint8_t data[6]; - // Helpers std::string toString() const { std::stringstream ss; for(size_t i = 0; i < 6; i++) { @@ -33,11 +33,25 @@ struct MACAddress { class EthernetMessage : public Frame { public: + // Standard Ethernet fields bool preemptionEnabled = false; uint8_t preemptionFlags = 0; std::optional fcs; bool frameTooShort = false; bool noPadding = false; + bool fcsVerified = false; + bool txAborted = false; + bool crcError = false; + bool isT1S = false; + + + bool isT1SSymbol = false; + bool isT1SBurst = false; + bool txCollision = false; + bool isT1SWake = false; + uint8_t t1sNodeId = 0; + uint8_t t1sBurstCount = 0; + uint8_t t1sSymbolType = 0; // Accessors const MACAddress& getDestinationMAC() const { return *(const MACAddress*)(data.data() + 0); }