#ifndef __ETHERNETPACKETIZER_H_ #define __ETHERNETPACKETIZER_H_ #ifdef __cplusplus #include "icsneo/api/eventmanager.h" #include #include #include namespace icsneo { /** * A layer of encapsulation on top of the standard packetizer * for 0xCAB1/0xCAB2 Ethernet packets. * * Not thread-safe by default. */ class EthernetPacketizer { public: static const size_t MaxPacketLength; EthernetPacketizer(device_eventhandler_t report) : report(report) {} /** * Call with as many packets as desired before calling * outputDown to get the results. Passing in multiple * packets may result in better packing. */ void inputDown(std::vector bytes, bool first = true); std::vector< std::vector > outputDown(); /** * Call with packet data, the packet may be queued waiting * for reassembly. In this case, false will be returned. */ bool inputUp(std::vector bytes); std::vector outputUp(); class EthernetPacket { public: // Don't worry about endian when setting fields, this is all taken care of in getBytestream EthernetPacket() {}; EthernetPacket(const std::vector& bytestream); EthernetPacket(const uint8_t* data, size_t size); int loadBytestream(const std::vector& bytestream); std::vector getBytestream() const; uint8_t errorWhileDecodingFromBytestream = 0; // Not part of final bytestream, only for checking the result of the constructor uint8_t destMAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; uint8_t srcMAC[6] = { 0x00, 0xFC, 0x70, 0xFF, 0xFF, 0xFF }; uint16_t etherType = 0xCAB1; // Big endian, Should be 0xCAB1 or 0xCAB2 uint32_t icsEthernetHeader = 0xAAAA5555; // Big endian, Should be 0xAAAA5555 uint16_t payloadSize = 0; // If this is a multi-piece message, this is the size of the expected reassembly // At this point in the packet, there is a 16-bit payload size, little endian // This is calculated from payload size in getBytestream uint16_t packetNumber = 0; bool firstPiece = true; // These booleans make up a 16-bit bitfield, packetInfo bool lastPiece = true; bool bufferHalfFull = false; std::vector payload; }; uint8_t hostMAC[6] = { 0x00, 0xFC, 0x70, 0xFF, 0xFF, 0xFF }; uint8_t deviceMAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; bool allowInPacketsFromAnyMAC = false; // Used when discovering devices private: bool reassembling = false; uint16_t reassemblingId = 0; std::vector reassemblingData; uint16_t sequenceDown = 0; std::vector processedUpBytes; std::vector processedDownPackets; device_eventhandler_t report; EthernetPacket& newSendPacket(bool first); }; } #endif // __cplusplus #endif