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
+46 -25
View File
@@ -3,6 +3,7 @@
#include "icsneo/communication/message/serialnumbermessage.h"
#include "icsneo/communication/message/resetstatusmessage.h"
#include "icsneo/communication/message/readsettingsmessage.h"
#include "icsneo/communication/message/canerrorcountmessage.h"
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
#include "icsneo/communication/command.h"
#include "icsneo/device/device.h"
@@ -24,7 +25,7 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) {
bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) {
switch(packet->network.getType()) {
case Network::Type::Ethernet:
case Network::Type::Ethernet: {
result = HardwareEthernetPacket::DecodeToMessage(packet->data, report);
if(!result) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
@@ -33,9 +34,11 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
EthernetMessage& eth = *static_cast<EthernetMessage*>(result.get());
eth.timestamp *= timestampResolution;
eth.network = packet->network;
return true;
}
case Network::Type::CAN:
case Network::Type::SWCAN:
case Network::Type::LSFTCAN: {
@@ -49,10 +52,28 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed
}
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
switch(result->type) {
case Message::Type::Frame: {
CANMessage& can = *static_cast<CANMessage*>(result.get());
can.network = packet->network;
break;
}
case Message::Type::CANErrorCount: {
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get());
can.network = packet->network;
break;
}
default: {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // An unknown type was returned, the packet was malformed
}
}
return true;
}
case Network::Type::FlexRay: {
@@ -66,10 +87,12 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed
}
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
FlexRayMessage& fr = *static_cast<FlexRayMessage*>(result.get());
fr.timestamp *= timestampResolution;
fr.network = packet->network;
return true;
}
case Network::Type::ISO9141: {
@@ -84,8 +107,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
ISO9141Message& iso = *static_cast<ISO9141Message*>(result.get());
iso.timestamp *= timestampResolution;
iso.network = packet->network;
return true;
}
case Network::Type::Internal: {
@@ -98,7 +122,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
HardwareResetStatusPacket* data = (HardwareResetStatusPacket*)packet->data.data();
auto msg = std::make_shared<ResetStatusMessage>();
msg->network = packet->network;
msg->mainLoopTime = data->main_loop_time_25ns * 25;
msg->maxMainLoopTime = data->max_main_loop_time_25ns * 25;
msg->busVoltage = data->busVoltage;
@@ -124,9 +147,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
// They come in as CAN but we will handle them in the device rather than
// passing them onto the user.
if(packet->data.size() < 24) {
result = std::make_shared<Message>();
result->network = packet->network;
result->data = packet->data;
auto rawmsg = std::make_shared<RawMessage>(Network::NetID::Device);
result = rawmsg;
rawmsg->data = packet->data;
return true;
}
@@ -135,17 +158,21 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed
}
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
auto* raw = dynamic_cast<RawMessage*>(result.get());
if(raw == nullptr) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed
}
raw->timestamp *= timestampResolution;
raw->network = packet->network;
return true;
}
case Network::NetID::DeviceStatus: {
result = std::make_shared<Message>();
result->network = packet->network;
// Just pass along the data, the device needs to handle this itself
result->data = packet->data;
result = std::make_shared<RawMessage>(packet->network, packet->data);
return true;
}
case Network::NetID::FlexRayControl: {
@@ -161,7 +188,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
switch((Command)packet->data[0]) {
case Command::RequestSerialNumber: {
auto msg = std::make_shared<SerialNumberMessage>();
msg->network = packet->network;
uint64_t serial = GetUInt64FromLEBytes(packet->data.data() + 1);
// The device sends 64-bits of serial number, but we never use more than 32-bits.
msg->deviceSerial = Device::SerialNumToString((uint32_t)serial);
@@ -194,7 +220,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
}
default:
auto msg = std::make_shared<Main51Message>();
msg->network = packet->network;
msg->command = Command(packet->data[0]);
msg->data.insert(msg->data.begin(), packet->data.begin() + 1, packet->data.end());
result = msg;
@@ -218,9 +243,8 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
}
case Network::NetID::ReadSettings: {
auto msg = std::make_shared<ReadSettingsMessage>();
msg->network = packet->network;
msg->response = ReadSettingsMessage::Response(packet->data[0]);
if(msg->response == ReadSettingsMessage::Response::OK) {
// The global settings structure is the payload of the message in this case
msg->data.insert(msg->data.begin(), packet->data.begin() + 10, packet->data.end());
@@ -243,9 +267,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
}
// For the moment other types of messages will automatically be decoded as raw messages
auto msg = std::make_shared<Message>();
msg->network = packet->network;
msg->data = packet->data;
result = msg;
result = std::make_shared<RawMessage>(packet->network, packet->data);
return true;
}