mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Device/Disk: Add VSA read and parse functionality
Implement ability to extract network traffic (CAN, LIN, Ethernet, etc.) from VSA message records on disk. Add a method to Device class that uses the VSAParser and the individual record types to extract messages from the VSA message records and pass them back to the communication system. This routes messages such that it appears as if they were discovered live instead of read from disk. The parse process (in Device) requires determination of metadata about the VSA file system on a device before it can begin extracting messages. This currently only handles data captured from the current coremini script on a device.
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
#ifndef __VSA_H__
|
||||
#define __VSA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/communication/packet.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include "stdint.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
using CaptureBitfield = uint16_t;
|
||||
|
||||
static constexpr uint64_t ICSEpochHoursSinceUnix = 13514 * 24; // Number of hours between the start of the Unix epoch and the start of the ICS epoch
|
||||
static constexpr uint64_t UINT63_MAX = 0x7FFFFFFFFFFFFFFFu;
|
||||
|
||||
/**
|
||||
* Struct that meets Clock format requirements from STL Chrono library.
|
||||
* Indicates time for for the ICS Epoch (January 1, 2007) in 25 nanosecond ticks.
|
||||
*/
|
||||
struct ICSClock {
|
||||
using rep = uint64_t; // Type for tick count
|
||||
using period = std::ratio_multiply<std::ratio<25>, std::nano>; // Ratio of tick length to seconds (25 nanoseconds)
|
||||
using duration = std::chrono::duration<rep, period>; // Type for duration in 25 nanosecond ticks
|
||||
using time_point = std::chrono::time_point<ICSClock>; // Type for a point in time with respect to ICSClock
|
||||
|
||||
static constexpr bool is_steady = true; // This clock does not move backwards
|
||||
|
||||
/**
|
||||
* Get the time_point at the current time with respect to ICSClock
|
||||
*
|
||||
* @return Time point at the current time with respect to ICSClock
|
||||
*/
|
||||
static time_point now() noexcept
|
||||
{
|
||||
return time_point { std::chrono::duration_cast<duration>(std::chrono::system_clock::now().time_since_epoch()) -
|
||||
std::chrono::hours(ICSEpochHoursSinceUnix) };
|
||||
}
|
||||
};
|
||||
|
||||
using Timestamp = ICSClock::time_point; // Point in time to start or stop read
|
||||
|
||||
class VSA;
|
||||
|
||||
/**
|
||||
* Holds metadata for the VSA log file
|
||||
*/
|
||||
struct VSAMetadata {
|
||||
uint64_t firstRecordLocation = UINT64_MAX; // Location of the record with lowest timestamp in ring buffer
|
||||
std::shared_ptr<VSA> firstRecord = nullptr; // The record with lowest timestamp
|
||||
uint64_t lastRecordLocation = UINT64_MAX; // Location of the record with the highest timestamp in ring buffer
|
||||
std::shared_ptr<VSA> lastRecord = nullptr; // The record with the highest timestamp
|
||||
uint64_t bufferEnd = UINT64_MAX; // One byte beyond the last byte of the sequence started from lastRecordLocation
|
||||
uint64_t diskSize = 0; // The size of the vsa log file on the disk
|
||||
bool isOverlapped = false; // Determines if VSA ring buffer has looped to beginning
|
||||
uint64_t coreMiniTimestamp = UINT64_MAX; // Timestamp of the CoreMini message in 25 nanosecond ticks since January 1, 2007
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct used to exclude VSA message records from parse
|
||||
*/
|
||||
struct VSAMessageReadFilter {
|
||||
CaptureBitfield captureBitfield = UINT16_MAX; // The capture from which to gather VSA message records. UINT16_MAX indicates 'all captures'
|
||||
|
||||
// The range of timestamps to collect record data from
|
||||
std::pair<Timestamp, Timestamp> readRange = std::make_pair(Timestamp(ICSClock::duration(0x0ull)), Timestamp(ICSClock::duration(UINT64_MAX)));
|
||||
|
||||
static constexpr Timestamp MinTimestamp = Timestamp(ICSClock::duration(0x0ull));
|
||||
static constexpr Timestamp MaxTimestamp = Timestamp(ICSClock::duration(UINT64_MAX));
|
||||
};
|
||||
|
||||
struct VSAExtractionSettings {
|
||||
bool parseOldRecords = false;
|
||||
bool stopCoreMini = true;
|
||||
std::vector<VSAMessageReadFilter> filters;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract VSA base class to store VSA record data read from VSA log file on disk
|
||||
*/
|
||||
class VSA {
|
||||
public:
|
||||
static constexpr size_t StandardRecordSize = 32; // Size of most VSA records
|
||||
static constexpr uint64_t RecordStartOffset = 0x06000000u; // Offset of VSA record ring buffer from start of VSA log file
|
||||
|
||||
/**
|
||||
* Convert the given time_point object to a timestamp in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return Timestamp of the given time_point in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
static uint64_t getICSTimestampFromTimepoint(const Timestamp& point) noexcept { return point.time_since_epoch().count(); }
|
||||
|
||||
/**
|
||||
* Enum to determine what type of record is underlying VSA parent class
|
||||
*/
|
||||
enum class Type : uint16_t {
|
||||
AA00 = 0xAA00u, // Pad
|
||||
AA01 = 0xAA01u, // Message Data (Deprecated)
|
||||
AA02 = 0xAA02u, // 'Logdata'
|
||||
AA03 = 0xAA03u, // Event
|
||||
AA04 = 0xAA04u, // Partition Info
|
||||
AA05 = 0xAA05u, // Application Error
|
||||
AA06 = 0xAA06u, // Internal/Debug
|
||||
AA07 = 0xAA07u, // Internal/Debug
|
||||
AA08 = 0xAA08u, // Buffer Info
|
||||
AA09 = 0xAA09u, // Device Info
|
||||
AA0A = 0xAA0Au, // Logger Configuration Info (Deprecated)
|
||||
AA0B = 0xAA0Bu, // Message Data
|
||||
AA0C = 0xAA0Cu, // PCM Audio Data
|
||||
AA0D = 0XAA0Du, // Message Data (Extended)
|
||||
AA0E = 0xAA0Eu, // Message Data (Extended)
|
||||
AA0F = 0xAA0Fu, // Message Data (Extended)
|
||||
AA6A = 0xAA6Au, // Logger Configuration Backup (512 Bytes)
|
||||
Invalid = UINT16_MAX // Used to indicate unset or unhandled VSA record types
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the record type
|
||||
*
|
||||
* @return Type of record
|
||||
*/
|
||||
Type getType() const { return type; }
|
||||
|
||||
/**
|
||||
* Get the timestamp stored in this record
|
||||
*
|
||||
* @return The record's timestamp in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
virtual uint64_t getTimestamp() = 0;
|
||||
|
||||
/**
|
||||
* Determine whether this record has a valid timestamp. All invalid timestamps are set to the maximum value for a uint64_t.
|
||||
*
|
||||
* @return True if the timestamp is set to a valid number
|
||||
*/
|
||||
bool isTimestampValid() { return getTimestamp() != UINT64_MAX && !checksumFailed; }
|
||||
|
||||
/**
|
||||
* Determine if the checksum for this record failed
|
||||
*
|
||||
* @return True if the checksum does not pass
|
||||
*/
|
||||
bool getChecksumFailed() { return checksumFailed; }
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in C++ native std::chrono::time_point
|
||||
*
|
||||
* @return Timestamp of record as an std::chrono::time_point
|
||||
*/
|
||||
Timestamp getTimestampICSClock()
|
||||
{
|
||||
return Timestamp(std::chrono::duration_cast<ICSClock::duration>(std::chrono::nanoseconds(getTimestamp() * 25)));
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Used to construct a VSA record from child class
|
||||
*/
|
||||
VSA() {}
|
||||
|
||||
/**
|
||||
* Used to set the type of this record in child class constructors
|
||||
*
|
||||
* @param recordType The type of this record
|
||||
*/
|
||||
void setType(Type recordType) { this->type = recordType; }
|
||||
|
||||
/**
|
||||
* Set whether the checksum was passed for this record. This is called in each child class constructor.
|
||||
*
|
||||
* @param fail True if checksum did not pass, else false
|
||||
*/
|
||||
void setChecksumFailed(bool fail) { checksumFailed = fail; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Performs checksum on data in specific record type. Calls VSA::setChecksumFailed(...) from child class.
|
||||
*
|
||||
* @param recordBytes Bytestream of record to perform checksum with
|
||||
*/
|
||||
virtual void doChecksum(uint8_t* recordBytes) = 0;
|
||||
|
||||
Type type = Type::Invalid; // The type of this record
|
||||
bool checksumFailed = false; // Determines if checksum failed
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface class for handling common functionality of VSAMessage record types (AA0B, AA0D, AA0E, AA0F)
|
||||
*/
|
||||
class VSAMessage : public VSA {
|
||||
public:
|
||||
static constexpr size_t CoreMiniPayloadSize = 24; // Size of CoreMini message (payload)
|
||||
|
||||
/**
|
||||
* Construct a packet from the message payload and network
|
||||
*
|
||||
* @return Packet constructed from payload and network
|
||||
*/
|
||||
std::shared_ptr<Packet> getPacket() const;
|
||||
|
||||
/**
|
||||
* Reserve enough memory to store a CoreMini message in the given packet
|
||||
*
|
||||
* @param packet The packet in which we are reserving memory for a message
|
||||
*/
|
||||
virtual void reservePacketData(std::shared_ptr<Packet>& packet) const { packet->data.reserve(CoreMiniPayloadSize); }
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this VSAMessage record during parsing
|
||||
*
|
||||
* @param filter The filter struct to check this message record against
|
||||
*
|
||||
* @return True if this message passes the given filter
|
||||
*/
|
||||
virtual bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor for normal instance of VSAMessage class
|
||||
*
|
||||
* @param messageBytes Bytestream that begins at the start of the message payload
|
||||
* @param numBytes The number of bytes that the message payload contains
|
||||
* @param networkId The CoreMini ID of the network for this message
|
||||
*/
|
||||
VSAMessage(uint8_t* const messageBytes, size_t numBytes, Network::CoreMini networkId = static_cast<Network::CoreMini>(UINT16_MAX))
|
||||
: VSA(), payload(messageBytes, messageBytes + numBytes), network(networkId) {}
|
||||
|
||||
std::vector<uint8_t> payload; // CoreMini message/payload of VSA record containing message data
|
||||
Network network; // CoreMini network of this message
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface class for handling common functionality of VSA Extended Message records (AA0D, AA0E, AA0F)
|
||||
*/
|
||||
class VSAExtendedMessage : public VSAMessage {
|
||||
public:
|
||||
static void truncatePacket(std::shared_ptr<Packet> packet);
|
||||
|
||||
/**
|
||||
* Appends the payload for this message to the given packet.
|
||||
* Also sets the network of the packet if unset (used primarily for AA0F records which do not contain the network in the first extended message record).
|
||||
*
|
||||
* @param packet The packet to append this record's payload to
|
||||
*/
|
||||
void appendPacket(std::shared_ptr<Packet> packet) const;
|
||||
|
||||
/**
|
||||
* Get the total number of records for this extended message
|
||||
*
|
||||
* @return Total number of records that this message spans
|
||||
*/
|
||||
uint32_t getRecordCount() const { return totalRecordCount; }
|
||||
|
||||
/**
|
||||
* Get the index of this record in the extended message sequence
|
||||
*
|
||||
* @return The index of this record
|
||||
*/
|
||||
uint16_t getIndex() { return index; };
|
||||
|
||||
/**
|
||||
* Get the numerical id of the sequence of extended message records this record is a part of
|
||||
*
|
||||
* @return The sequence number of this extended message record
|
||||
*/
|
||||
uint16_t getSequenceNum() { return sequenceNum; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor for normal instance of VSAExtendedMessage
|
||||
*
|
||||
* @param messageBytes Bytestream that begins at the start of the message payload
|
||||
* @param numBytes The length of the message payload in bytes
|
||||
* @param networkId The CoreMini ID of the network for this message
|
||||
*/
|
||||
VSAExtendedMessage(uint8_t* const messageBytes, size_t numBytes, Network::CoreMini networkId = static_cast<Network::CoreMini>(UINT16_MAX))
|
||||
: VSAMessage(messageBytes, numBytes, networkId) {}
|
||||
|
||||
/**
|
||||
* Set the total number of records for this message
|
||||
*
|
||||
* @param recordCount Total number of records for this message
|
||||
*/
|
||||
void setRecordCount(uint32_t recordCount) { totalRecordCount = recordCount; }
|
||||
|
||||
/**
|
||||
* Set the index of this record
|
||||
*
|
||||
* @param recordIndex The index of this record in its extended message sequence
|
||||
*/
|
||||
void setIndex(uint16_t recordIndex) { this->index = recordIndex; }
|
||||
|
||||
/**
|
||||
* Set the sequence number of this record
|
||||
*
|
||||
* @param seq The id for the extended message sequence this record is a part of
|
||||
*/
|
||||
void setSequenceNum(uint16_t seq) { sequenceNum = seq; }
|
||||
|
||||
private:
|
||||
uint32_t totalRecordCount; // The total number of records for the extended message
|
||||
uint16_t index; // The index of this record in its extended message sequence
|
||||
uint16_t sequenceNum; // The id of the sequence of records this record is a part of
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA_H__
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef __VSA02_H__
|
||||
#define __VSA02_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that contains data for Logdata records
|
||||
*/
|
||||
class VSA02 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses the given bytestream
|
||||
*
|
||||
* @param bytes Bystream that contains data for Logdata VSA records
|
||||
*/
|
||||
VSA02(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum for this record
|
||||
*
|
||||
* @param bytes Bystream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t constantIndex; // Index into CoreMini binary where constant data for this record can be found
|
||||
struct Flags {
|
||||
bool hasMoreData : 1; // Set to true if there are further Logdata records expected to terminate this "chain"
|
||||
uint8_t numSamples : 3; // Number of valid samples in samples
|
||||
bool isAscii : 1; // Set to true if the processing code should treat samples as an ASCII string
|
||||
bool prefixTime : 1; // Set to true if the function block step that created this record requested that the timestamp be prepended on the output
|
||||
bool sample0IsHex : 1; // Set to true if the value in sample 0 should be written as hex
|
||||
bool sample1IsHex : 1; // Set to true if the value in sample 1 shoudl be written as hex
|
||||
} flags; // Series of flags for this record
|
||||
uint8_t pieceCount; // Value of the rolling counter for this "chain" of logdata records
|
||||
uint64_t timestamp; // Timestamp in 25 nanosecond ticks since January 1, 2007
|
||||
std::vector<uint8_t> samples; // Data for this record that varies based on the above flags. Either 2 32.32 fixed point values or 16 byte ASCII string
|
||||
uint16_t checksum; // The sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA02_H__
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef __VSA03_H__
|
||||
#define __VSA03_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class used to store event
|
||||
*/
|
||||
class VSA03 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor that extracts data from the given bytestream
|
||||
*
|
||||
* @param bytes Bytestream to extract VSA record data from
|
||||
*/
|
||||
VSA03(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum for this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
enum class EventType : uint16_t {
|
||||
CaptureStarted = 0,
|
||||
StorageReconnected = 3,
|
||||
FileSystemBufferOverflow = 4,
|
||||
LoggerWentToSleep = 5,
|
||||
Internal = 7,
|
||||
CaptureStopped = 8,
|
||||
LoggerPowerEvent = 9
|
||||
} eventType; // Enumerated value indicating which type of event occurred
|
||||
uint16_t eventData; // Information about the event that is dependent on eventType
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // The sum of the previous 7 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA03_H__
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef __VSA04_H__
|
||||
#define __VSA04_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that contains a partition info record
|
||||
*/
|
||||
class VSA04 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor that created partition info record from bytestream
|
||||
*
|
||||
* @param bytes Bytestream to create this record from
|
||||
*/
|
||||
VSA04(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum for this record
|
||||
*
|
||||
* @param bytes Bytestream to check against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
struct Flags {
|
||||
bool invalidRequestDetected : 1; // Indicates if an invalid request was detected
|
||||
uint16_t reserved : 15; // Empty flag bits
|
||||
} flags; // Mostly empty field for flags
|
||||
uint16_t partitionIndex; // The index of the partition containing this record
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 7 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA04_H__
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef __VSA05_H__
|
||||
#define __VSA05_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that holds data for application error records
|
||||
*/
|
||||
class VSA05 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert bytestream into application error record
|
||||
*
|
||||
* @param bytes The bytestream containing the record data
|
||||
*/
|
||||
VSA05(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
enum class ErrorType : uint16_t {
|
||||
NetworkReceiveBufferOverflow = 0,
|
||||
NetworkTransmitBufferOverflow = 1,
|
||||
NetworkTransmitReportBufferOverflow = 2,
|
||||
PeripheralProcessorCommunicationError = 3,
|
||||
NetworkPeripheralOverflow = 4,
|
||||
CommunicationPacketChecksumError = 6,
|
||||
CommunicationPacketDetectedMissingByte = 7,
|
||||
FailedToApplySettingsToNetwork = 9,
|
||||
EnabledNetworkCountExceedsLicenseCapability = 10,
|
||||
NetworkNotEnabled = 11,
|
||||
DetectedInvalidTimestamp = 12,
|
||||
LoadedDefaultSettings = 13,
|
||||
DeviceAttemptedUnsupportedOperation = 14,
|
||||
TrasmitBufferFillExceededThreshold = 17,
|
||||
TransmitRequestedOnInvalidNetwork = 18,
|
||||
TransmitRequestedOnTransmitIncapableNetwork = 19,
|
||||
TransmitRequestedWhileControllersInactive = 20,
|
||||
FilterMatchesExceedLimit = 21,
|
||||
EthernetPreemptionError = 22,
|
||||
TransmitWhileControllerModeInvalid = 23,
|
||||
FragmentedEthernetIPFrame = 25,
|
||||
TransmitBufferUnderrun = 26,
|
||||
ActiveCoolingFailureDetected = 27,
|
||||
OvertemperatureConditionDetected = 28,
|
||||
UndersizedEthernetFrame = 30,
|
||||
OversizedEthernetFrame = 31,
|
||||
SystemWatchdogEventOcurred = 32,
|
||||
SystemClockFailureDetected = 33,
|
||||
RecoveredFromSystemClockFailure = 34,
|
||||
SystemResetFailedPeripheralComponent = 35,
|
||||
FailedToInitializeLoggerDisk = 41,
|
||||
AttemptedToApplyInvalidSettingsToNetwork = 42
|
||||
} errorType; // Enumerated value indicating the type of error that occurred
|
||||
uint16_t errorNetwork; // When applicable, the enumerated network index that the error occurred on
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 7 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA05_H__
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef __VSA06_H__
|
||||
#define __VSA06_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that holds data for an internal/debug VSA record
|
||||
*/
|
||||
class VSA06 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert bytestream into internal/debug record
|
||||
*
|
||||
* @param bytes Bytestream to parse into internal/debug record
|
||||
*/
|
||||
VSA06(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
std::vector<uint32_t> savedSectors; // Unknown
|
||||
uint16_t error; // Unknown
|
||||
uint16_t savedSectorsHigh; // Unknown
|
||||
uint64_t timestamp; // Timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA06_H__
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef __VSA07_H__
|
||||
#define __VSA07_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that holds data for an internal/debug VSA record
|
||||
*/
|
||||
class VSA07 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert bytestream into internal/debug record
|
||||
*
|
||||
* @param bytes Bytestream to parse into internal/debug record
|
||||
*/
|
||||
VSA07(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t lastSector; // Unknown
|
||||
uint32_t currentSector; // Unknown
|
||||
std::vector<uint8_t> reserved; // Unused bytes (12 bytes)
|
||||
uint64_t timestamp; // Timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA07_H__
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef __VSA08_H__
|
||||
#define __VSA08_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class to store data for a buffer information record
|
||||
*/
|
||||
class VSA08 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert a bytestream to a buffer info record
|
||||
*
|
||||
* @param bytes Bytestream to convert into a buffer record
|
||||
*/
|
||||
VSA08(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
std::vector<uint8_t> troubleSramCount; // Unknown (4 bytes)
|
||||
std::vector<uint32_t> troubleSectors; // Unknown (16 bytes)
|
||||
uint64_t timestamp; // Timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA08_H__
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef __VSA09_H__
|
||||
#define __VSA09_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class used to store data for a Device Information VSA Record
|
||||
*/
|
||||
class VSA09 : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert bytestream to Device Information VSA Record
|
||||
*
|
||||
* @param bytes Bytestream to convert into Device Information Record
|
||||
*/
|
||||
VSA09(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t serialNumber; // Decimal representation of Base-36 serial number
|
||||
uint8_t firmwareMajorVersion; // Major version of firmware (A for A.B version)
|
||||
uint8_t firmwareMinorVersion; // Minor version of firmware (B for A.B version)
|
||||
uint8_t manufactureMajorRevision; // Major version of manufacture revision (A for A.B revision)
|
||||
uint8_t manufactureMinorRevision; // Minor version of manufacture revision (B for A.B revision)
|
||||
uint8_t bootloaderMajorVersion; // Major version of bootloader (A for A.B version)
|
||||
uint8_t bootloaderMinorVersion; // Minor version of bootloader (B for A.B version)
|
||||
std::vector<uint8_t> reserved0; // Unused bytes (6 bytes)
|
||||
enum class HardwareID : uint8_t {
|
||||
NeoVIRED = 0,
|
||||
NeoVIFIRE = 1,
|
||||
NeoVIION = 11,
|
||||
RADGalaxy = 19,
|
||||
RADMars = 29,
|
||||
ValueLOG = 31,
|
||||
NeoVIRED2FIRE3 = 33,
|
||||
RADGigastar = 36
|
||||
} hardwareID; // Identifier for specific hardware device type
|
||||
std::vector<uint8_t> reserved1; // Unused bytes (3 bytes)
|
||||
uint64_t timestamp; // Timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA09_H__
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef __VSA0B_H__
|
||||
#define __VSA0B_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <vector>
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that holds single-record message records
|
||||
*/
|
||||
class VSA0B : public VSAMessage {
|
||||
public:
|
||||
/**
|
||||
* Constructor that reads message record data from bytestream
|
||||
*
|
||||
* @param bytes Bytestream to read message record data from
|
||||
*/
|
||||
VSA0B(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if this record has passed the filter (i.e., is not being filtered out)
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override;
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform a checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t captureBitfield; // The capture that this record is a part of
|
||||
uint8_t reserved; // Unused bytes
|
||||
uint16_t checksum; // Sum of the previous 15 half words
|
||||
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007 (extracted from CoreMini message payload)
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA0B_H__
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef __VSA0C_H__
|
||||
#define __VSA0C_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class used to hold data for a PCM Audio VSA Record
|
||||
*/
|
||||
class VSA0C : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert bytestream to PCM Audio Record
|
||||
*
|
||||
* @param bytes Bytestream to parse
|
||||
*/
|
||||
VSA0C(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t captureBitfield; // Capture this record is a member of (Unused)
|
||||
uint8_t audioPreamble; // Unknown
|
||||
uint8_t audioHeader; // Unknown
|
||||
std::vector<uint8_t> pcmData; // Audio data payload (14 bytes)
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
struct VNet {
|
||||
uint16_t vNetSlot : 2; // Bits to identify VNet slot of this record
|
||||
uint16_t reserved : 14; // Unused bits
|
||||
} vNetBitfield; // Struct to ensure VNetSlot is only 2 bits
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA0C_H__
|
||||
@@ -0,0 +1,134 @@
|
||||
#ifndef __VSA0D_H__
|
||||
#define __VSA0D_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Base class for VSA0D extended message record types
|
||||
*/
|
||||
class VSA0D : public VSAExtendedMessage {
|
||||
public:
|
||||
/**
|
||||
* Constructor for VSA0D parent class. Passes most information to VSAExtendedMessage constructor.
|
||||
*
|
||||
* @param bytes Bytestream to read record data from
|
||||
* @param messageBytes Bytestream starting at the payload of this message record
|
||||
* @param numBytes The length of the payload of this message record
|
||||
* @param runningChecksum Checksum for the payload bytes of this sequence of extended message records
|
||||
* @param networkId The CoreMini Network ID for this record
|
||||
*/
|
||||
VSA0D(uint8_t* const bytes, uint8_t* const messageBytes, size_t numBytes, uint32_t& runningChecksum, Network::CoreMini networkId = static_cast<Network::CoreMini>(0xFFFFu));
|
||||
};
|
||||
|
||||
/**
|
||||
* Class holding data for the first record in a series of VSA0D extended message records
|
||||
*/
|
||||
class VSA0DFirst : public VSA0D {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of bytestream into readable data.
|
||||
*
|
||||
* @param bytes Bytestream to parse VSA record from
|
||||
*/
|
||||
VSA0DFirst(uint8_t* const bytes, uint32_t& runningChecksum);
|
||||
|
||||
/**
|
||||
* Reserve memory in the packet data vector to store message data from this record and subsequent consecutive records.
|
||||
*
|
||||
* @param packet The packet to reserve memory in
|
||||
*/
|
||||
void reservePacketData(std::shared_ptr<Packet>& packet) const override;
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if the record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override;
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record. Timestamp indicates number of 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return The timestamp of this record
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
/**
|
||||
* Reorder bytes in the payload between this record and the second record in the sequence. The bytes are reordered to allow
|
||||
* simple concatenation of payload bytes from records before creating and dispatching a packet.
|
||||
*
|
||||
* @param secondPayload Reference to the payload from the second record in the sequence
|
||||
*/
|
||||
void reorderPayload(std::vector<uint8_t>& secondPayload);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum on this record with the given bytestream
|
||||
*
|
||||
* @param bytes The bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t captureBitfield; // The data capture this record is a part of
|
||||
uint64_t timestamp; // The timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
struct VNet {
|
||||
uint8_t vNetSlot : 2; // VNet bytes
|
||||
uint8_t reserved : 6; // Unused bytes
|
||||
} vNetInfo; // Struct used to indicate which bytes are actually used for VNetSlot
|
||||
uint16_t checksum; // The sum of the previous 15 words
|
||||
};
|
||||
|
||||
/**
|
||||
* Class holding data for subsequent records in series of VSA0D extended message records
|
||||
*/
|
||||
class VSA0DConsecutive : public VSA0D {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of VSA0D record
|
||||
* @param bytes Bytestream to read VSA record data from
|
||||
* @param first The first record in this series of VSA0D records
|
||||
* @param isLastRecord Determines if this record is the last record in this series of extended message records
|
||||
*/
|
||||
VSA0DConsecutive(uint8_t* const bytes, uint32_t& runningChecksum, std::shared_ptr<VSA0DFirst> first, bool isLastRecord = false);
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record. Utilizes the filter from the first record.
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if this record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override { return first ? first->filter(filter) : false; }
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return Timestamp in 25 nanosecond ticks since January 1, 2007.
|
||||
*/
|
||||
uint64_t getTimestamp() override { return first ? first->getTimestamp() : UINT64_MAX; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum on this record with the given bytestream
|
||||
*
|
||||
* @param bytes The bytestream to test the checksum against
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t recordChecksum; // The checksum for this extended record sequence found in the last record (not used if not last record)
|
||||
|
||||
uint32_t calculatedChecksum = 0; // Running checksum total for the extended record sequence of this record
|
||||
|
||||
std::shared_ptr<VSA0DFirst> first = nullptr; // The first record in this extended message record series
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif //__cplusplus
|
||||
#endif // __VSA0D_H__
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifndef __VSA0E_H__
|
||||
#define __VSA0E_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Base class for VSA0E extended message record types
|
||||
*/
|
||||
class VSA0E : public VSAExtendedMessage {
|
||||
public:
|
||||
/**
|
||||
* Constructor for VSA0E parent class. Passes most information to VSAExtendedMessage constructor.
|
||||
*
|
||||
* @param bytes Bytestream to read record data from
|
||||
* @param messageBytes Bytestream starting at the payload of this message record
|
||||
* @param numBytes The length of the payload of this message record
|
||||
* @param runningChecksum Checksum for the payload bytes of this sequence of extended message records
|
||||
* @param networkId The CoreMini Network ID for this record
|
||||
*/
|
||||
VSA0E(uint8_t* const bytes, uint8_t* const messageBytes, size_t numBytes, uint32_t& runningChecksum, Network::CoreMini networkId = static_cast<Network::CoreMini>(0xFFFFu));
|
||||
};
|
||||
|
||||
/**
|
||||
* Class holding data for the first record in a series of VSA0E extended message records
|
||||
*/
|
||||
class VSA0EFirst : public VSA0E {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of bytestream into readable data.
|
||||
*
|
||||
* @param bytes Bytestream to parse VSA record from
|
||||
*/
|
||||
VSA0EFirst(uint8_t* const bytes, uint32_t& runningChecksum);
|
||||
|
||||
/**
|
||||
* Reserve memory in the packet data vector to store message data from this record and subsequent consecutive records.
|
||||
*
|
||||
* @param packet The packet to reserve memory in
|
||||
*/
|
||||
void reservePacketData(std::shared_ptr<Packet>& packet) const override;
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if the record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override;
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record. Timestamp indicates number of 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return The timestamp of this record
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
/**
|
||||
* Reorder bytes in the payload between this record and the second record in the sequence. The bytes are reordered to allow
|
||||
* simple concatenation of payload bytes from records before creating and dispatching a packet.
|
||||
*
|
||||
* @param secondPayload Reference to the payload from the second record in the sequence
|
||||
*/
|
||||
void reorderPayload(std::vector<uint8_t>& secondPayload);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t captureBitfield; // The data capture this record is a part of
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // Sum of the previous 15 words
|
||||
};
|
||||
|
||||
/**
|
||||
* Class holding data for subsequent records in series of VSA0E extended message records
|
||||
*/
|
||||
class VSA0EConsecutive : public VSA0E {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of VSA0E record
|
||||
* @param bytes Bytestream to read VSA record data from
|
||||
* @param first The first record in this series of VSA0E records
|
||||
* @param isLastRecord Determines if this record is the last record in this series of extended message records
|
||||
*/
|
||||
VSA0EConsecutive(uint8_t* const bytes, uint32_t& runningChecksum, std::shared_ptr<VSA0EFirst> first, bool isLastRecord = false);
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record. Utilizes the filter from the first record.
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if this record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override { return first ? first->filter(filter) : false; }
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return Timestamp in 25 nanosecond ticks since January 1, 2007.
|
||||
*/
|
||||
uint64_t getTimestamp() override { return first ? first->getTimestamp() : UINT64_MAX; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum on this record with the given bytestream
|
||||
*
|
||||
* @param bytes The bytestream to test the checksum against
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t recordChecksum; // The checksum for this extended record sequence found in the last record (not used if not last record)
|
||||
|
||||
uint32_t calculatedChecksum; // Running checksum total for the extended record sequence of this record
|
||||
|
||||
std::shared_ptr<VSA0EFirst> first = nullptr; // The first record in this series of extended message records
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif //__cplusplus
|
||||
#endif // __VSA0E_H__
|
||||
@@ -0,0 +1,119 @@
|
||||
#ifndef __VSA0F_H__
|
||||
#define __VSA0F_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Base class for VSA0F extended message record types
|
||||
*/
|
||||
class VSA0F : public VSAExtendedMessage {
|
||||
public:
|
||||
/**
|
||||
* Standard constructor for VSA0F parent class. Passes most information to VSAExtendedMessage constructor.
|
||||
*
|
||||
* @param bytes Bytestream to read record data from
|
||||
* @param messageBytes Bytestream starting at the payload of this message record
|
||||
* @param numBytes The length of the payload of this message record
|
||||
* @param runningChecksum Checksum for the payload bytes of this sequence of extended message records
|
||||
* @param networkId The CoreMini Network ID for this record
|
||||
*/
|
||||
VSA0F(uint8_t* const bytes, uint8_t* const messageBytes, size_t numBytes, uint32_t& runningChecksum, Network::CoreMini networkId = static_cast<Network::CoreMini>(0xFFFFu));
|
||||
};
|
||||
|
||||
/**
|
||||
* Class holding data for the first record in a series of VSA0F extended message records
|
||||
*/
|
||||
class VSA0FFirst : public VSA0F {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of bytestream into readable data.
|
||||
*
|
||||
* @param bytes Bytestream to parse VSA record from
|
||||
*/
|
||||
VSA0FFirst(uint8_t* const bytes, uint32_t& runningChecksum);
|
||||
|
||||
/**
|
||||
* Reserve memory in the packet data vector to store message data from this record and subsequent consecutive records.
|
||||
*
|
||||
* @param packet The packet to reserve memory in
|
||||
*/
|
||||
void reservePacketData(std::shared_ptr<Packet>& packet) const override;
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if the record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override;
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record. Timestamp indicates number of 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return The timestamp of this record
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum on this record with the given bytestream
|
||||
*
|
||||
* @param bytes The bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint16_t captureBitfield; // The data capture this record is a part of
|
||||
uint64_t timestamp; // The timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t checksum; // The sum of the previous 9 words (Does not include message payload since payload bits follow the checksum)
|
||||
};
|
||||
/**
|
||||
* Class holding data for subsequent records in series of VSA0D extended message records
|
||||
*/
|
||||
class VSA0FConsecutive : public VSA0F {
|
||||
public:
|
||||
/**
|
||||
* Constructor that parses first 32 bytes of VSA0F record
|
||||
* @param bytes Bytestream to read VSA record data from
|
||||
* @param first The first record in this series of VSA0F records
|
||||
* @param isLastRecord Determines if this record is the last record in this series of extended message records
|
||||
*/
|
||||
VSA0FConsecutive(uint8_t* const bytes, uint32_t& runningChecksum, std::shared_ptr<VSA0FFirst> first, bool isLastRecord = false);
|
||||
|
||||
/**
|
||||
* Determine whether to filter out this message record. Utilizes the filter from the first record.
|
||||
*
|
||||
* @param filter The filter to check this record against
|
||||
*
|
||||
* @return True if this record passes the filter
|
||||
*/
|
||||
bool filter(const std::shared_ptr<VSAMessageReadFilter> filter) override { return first ? first->filter(filter) : false; }
|
||||
|
||||
/**
|
||||
* Get the timestamp of this record in 25 nanosecond ticks since January 1, 2007.
|
||||
*
|
||||
* @return Timestamp in 25 nanosecond ticks since January 1, 2007.
|
||||
*/
|
||||
uint64_t getTimestamp() override { return first ? first->getTimestamp() : UINT64_MAX; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform checksum on this record with the given bytestream
|
||||
*
|
||||
* @param bytes The bytestream to test the checksum against
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t calculatedChecksum; // Running checksum total for the extended record sequence of this record
|
||||
|
||||
std::shared_ptr<VSA0FFirst> first = nullptr; // The first record in this series of extended message records
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif //__cplusplus
|
||||
#endif // __VSA0F_H__
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef __VSA6A_H__
|
||||
#define __VSA6A_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class that contains data for a Logger Configuration Backup Record
|
||||
*/
|
||||
class VSA6A : public VSA {
|
||||
public:
|
||||
/**
|
||||
* Constructor to convert a bytestream to a Logger Configuration Backup Record
|
||||
*
|
||||
* @param bytes Bytestream to convert to Logger Configuration Backup Record
|
||||
*/
|
||||
VSA6A(uint8_t* const bytes);
|
||||
|
||||
/**
|
||||
* Get the timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*
|
||||
* @return The timestamp for this record in 25 nanosecond ticks since January 1, 2007
|
||||
*/
|
||||
uint64_t getTimestamp() override { return timestamp; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Perform the checksum on this record
|
||||
*
|
||||
* @param bytes Bytestream to test against the checksum
|
||||
*/
|
||||
void doChecksum(uint8_t* bytes) override;
|
||||
|
||||
uint32_t sequenceNum; // Unknown
|
||||
uint32_t totalSectors; // Unknown
|
||||
uint32_t reserved; // Unused bytes
|
||||
uint64_t timestamp; // Timestamp of this record in 25 nanosecond ticks since January 1, 2007
|
||||
uint16_t timestampSum; // Sum of the bytes in this record's timestamp (previous 8 bytes)
|
||||
std::vector<uint8_t> data; // Payload data for this record (452 bytes)
|
||||
uint32_t checksum; // Sum of the previous 452 bytes (bytes from data)
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSA6A_H__
|
||||
@@ -0,0 +1,234 @@
|
||||
#ifndef __VSAPARSER_H__
|
||||
#define __VSAPARSER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
#include "icsneo/disk/vsa/vsa0d.h"
|
||||
#include "icsneo/disk/vsa/vsa0e.h"
|
||||
#include "icsneo/disk/vsa/vsa0f.h"
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
/**
|
||||
* Class used to parse VSA records from bytestreams
|
||||
*/
|
||||
class VSAParser {
|
||||
public:
|
||||
/**
|
||||
* Struct that determines which types of VSA records to extract from disk
|
||||
*/
|
||||
struct Settings {
|
||||
bool extractAA02 = true; // Extract Logdata Records
|
||||
bool extractAA03 = true; // Extract Event Records
|
||||
bool extractAA04 = true; // Extract Partition Info Records
|
||||
bool extractAA05 = true; // Extract Application Error Records
|
||||
bool extractAA06 = true; // Extract Debug/Internal 1 Records
|
||||
bool extractAA07 = true; // Extract Debug/Internal 2 Records
|
||||
bool extractAA08 = true; // Extract Buffer Info Records
|
||||
bool extractAA09 = true; // Extract Device Info Records
|
||||
bool extractAA0B = true; // Extract Message Records
|
||||
bool extractAA0C = true; // Extract PCM Audio Records
|
||||
bool extractAA0D = true; // Extract Extended Message 1 Records
|
||||
bool extractAA0E = true; // Extract Extended Message 2 Records
|
||||
bool extractAA0F = true; // Extract Extended Message 3 Records
|
||||
bool extractAA6A = true; // Extract Logger Configuration Backup Records
|
||||
|
||||
std::shared_ptr<VSAMessageReadFilter> messageFilter = nullptr; // Used for post-read filtering of message records
|
||||
|
||||
/**
|
||||
* Static constructor for VSAParser::Settings that only extracts message records (AA0B, AA0D, AA0E, AA0F)
|
||||
*/
|
||||
static Settings messageRecords() { return { false, false, false, false, false, false, false, false, true, false, true, true, true, false }; }
|
||||
|
||||
/**
|
||||
* Operator overload for equivalency of VSAParser::Settings struct
|
||||
*
|
||||
* @param s The settings object to test against this settings object
|
||||
*
|
||||
* @return True if the extraction settings are the same. Does not check the filter
|
||||
*/
|
||||
bool operator==(const Settings& s)
|
||||
{
|
||||
return s.extractAA02 == this->extractAA02 && s.extractAA03 == this->extractAA03 && s.extractAA04 == this->extractAA04 &&
|
||||
s.extractAA05 == this->extractAA05 && s.extractAA06 == this->extractAA06 && s.extractAA07 == this->extractAA07 &&
|
||||
s.extractAA08 == this->extractAA08 && s.extractAA09 == this->extractAA09 && s.extractAA0B == this->extractAA0B &&
|
||||
s.extractAA0C == this->extractAA0C && s.extractAA0D == this->extractAA0D && s.extractAA0E == this->extractAA0E &&
|
||||
s.extractAA0F == this->extractAA0F && s.extractAA6A == this->extractAA6A;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator overload for non-equivalency of VSAParser::Settings struct
|
||||
*
|
||||
* @param s The settings object to test against this settings object
|
||||
*
|
||||
* @return True if the extraction settings are not the same. Does not check the filter
|
||||
*/
|
||||
bool operator!=(const Settings& s)
|
||||
{
|
||||
return !(*this == s);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumerated values to determine status of attempt to parse out-of-context record from bytestream
|
||||
*/
|
||||
enum class RecordParseStatus : uint8_t {
|
||||
NotARecordStart, // Indicates first byte was not of format required for VSA records
|
||||
Pad, // This record is a pad record
|
||||
Deprecated, // This record is deprecated
|
||||
ConsecutiveExtended, // This is a consecutive extended message record (i.e., not the first record in an extended message sequence)
|
||||
FilteredOut, // This record was filtered out due to the current Settings of the VSAParser
|
||||
UnknownRecordType, // The second byte indicates a record type that is unknown/not handled
|
||||
InsufficientData, // There were not enough bytes given to the parse call
|
||||
Success // The record was successfully parsed
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor with default settings
|
||||
*
|
||||
* @param report Handler to report APIEvents
|
||||
*/
|
||||
VSAParser(const device_eventhandler_t& report) { this->report = report; }
|
||||
|
||||
/**
|
||||
* Constructor with non-default settings
|
||||
*
|
||||
* @param report Handler to report APIEvents
|
||||
* @param settings The settings to use for this parser
|
||||
*/
|
||||
VSAParser(const device_eventhandler_t& report, const Settings& settings)
|
||||
: settings(settings) { this->report = report; }
|
||||
|
||||
/**
|
||||
* Parse the given bytestream into VSA records and store them in vsaRecords.
|
||||
* Non-terminated extended message record sequences are stored in a temporary buffer until they terminate.
|
||||
*
|
||||
* @param bytes Bytestream to parse VSA records from
|
||||
* @param arrLen The number of bytes in the bytestream
|
||||
*
|
||||
* @return True if there was no failure or unhandled behavior during parse, else false
|
||||
*/
|
||||
bool parseBytes(uint8_t* const bytes, uint64_t arrLen);
|
||||
|
||||
/**
|
||||
* Get the last fully-parsed record in the parser
|
||||
*/
|
||||
std::shared_ptr<VSA>& back() { return vsaRecords.back(); }
|
||||
|
||||
/**
|
||||
* Get the number of records contained within the parser
|
||||
*
|
||||
* @return Size of the vector of VSA records
|
||||
*/
|
||||
size_t size() { return vsaRecords.size(); }
|
||||
|
||||
/**
|
||||
* Determine if number of records contained within the parser is 0
|
||||
*
|
||||
* @return True if the parser record container is empty
|
||||
*/
|
||||
bool empty() { return vsaRecords.empty(); }
|
||||
|
||||
/**
|
||||
* Clear all fully-parsed records from the parser. Does not affect non-terminated extended message records stored in buffers.
|
||||
*/
|
||||
void clearRecords() { vsaRecords.clear(); }
|
||||
|
||||
/**
|
||||
* Parse first record from the given bytestream.
|
||||
*
|
||||
* @param bytes The bytestream to read from
|
||||
* @param arrLen Length of the bytestream
|
||||
* @param record Variable to pass out the record if able to parse
|
||||
*
|
||||
* @return The status of the record parse
|
||||
*/
|
||||
RecordParseStatus getRecordFromBytes(uint8_t* const bytes, size_t arrLen, std::shared_ptr<VSA>& record);
|
||||
|
||||
/**
|
||||
* Set a message filter for the Settings for this VSAParser
|
||||
*
|
||||
* @param filter The message filter to set for this VSAParser
|
||||
*/
|
||||
void setMessageFilter(const VSAMessageReadFilter& filter) { settings.messageFilter = std::make_shared<VSAMessageReadFilter>(filter); }
|
||||
|
||||
/**
|
||||
* Remove the message filter for the Settings from this parser
|
||||
*/
|
||||
void clearMessageFilter() { settings.messageFilter = nullptr; }
|
||||
|
||||
/**
|
||||
* Clear all extended message buffers and parse states
|
||||
*/
|
||||
void clearParseState();
|
||||
|
||||
/**
|
||||
* Extract all packets from fully-parsed VSA records and store them in the given buffer
|
||||
*
|
||||
* @param packets The vector in which to store the packets from fully-parsed records
|
||||
*
|
||||
* @return True if packets were successfully extracted
|
||||
*/
|
||||
bool extractMessagePackets(std::vector<std::shared_ptr<Packet>>& packets);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Holds the state of all possible extended message record sequences (most will be empty/null)
|
||||
*/
|
||||
struct ExtendedMessageState {
|
||||
/**
|
||||
* Holds the state of a single extended message record sequence
|
||||
*/
|
||||
struct ExtendedRecordSeqInfo {
|
||||
/**
|
||||
* Reset the state of this record sequence
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
nextIndex = 0;
|
||||
totalRecordCount = 0;
|
||||
runningChecksum = 0;
|
||||
records.clear();
|
||||
records.shrink_to_fit();
|
||||
}
|
||||
|
||||
uint16_t nextIndex = 0; // The next index to be parsed in this sequence
|
||||
uint32_t totalRecordCount = 0; // The total number of records that are in this sequence
|
||||
uint32_t runningChecksum = 0; // The running calculated checksum for this sequence
|
||||
|
||||
std::vector<std::shared_ptr<VSAExtendedMessage>> records; // All of the records in this sequence
|
||||
};
|
||||
|
||||
std::array<ExtendedRecordSeqInfo, 128> vsa0DSeqInfo; // Holds state for each possible sequence ID for VSA0D
|
||||
std::array<ExtendedRecordSeqInfo, 256> vsa0ESeqInfo; // Holds state for each possible sequence ID for VSA0E
|
||||
std::array<ExtendedRecordSeqInfo, 128> vsa0FSeqInfo; // Holds state for each possible sequence ID for VSA0F
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle parsing of extended message records
|
||||
*
|
||||
* @param bytes The bytestream to parse the extended message record from
|
||||
* @param bytesOffset The offset in the bytestream to read the record from
|
||||
* @param type The type of VSA extended message record that we are parsing (AA0D, AA0E, AA0F)
|
||||
*
|
||||
* @return True if no unhandled failures to parse occurred
|
||||
*/
|
||||
bool handleExtendedRecord(uint8_t* const bytes, uint64_t& bytesOffset, VSA::Type type);
|
||||
|
||||
std::vector<std::shared_ptr<VSA>> vsaRecords; // The vector of records that this parser has parsed
|
||||
bool hasDeprecatedRecords = false; // Indicates whether records of deprecated types are present in the disk
|
||||
Settings settings; // The settings used to determine which records to save to records vector
|
||||
ExtendedMessageState state; // The parse state of all possible extended message sequences
|
||||
device_eventhandler_t report; // Event handler to report APIEvents
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __VSAPARSER_H__
|
||||
Reference in New Issue
Block a user