Communication: Fix NetID VNET conflict

There exists a potential conflict with some existing NetIDs and VNET NetIDs in the 200 range. To resolve this there is now an additional optional "expand" argument in various functions that could conflict. In most situations this should be false, and is false for MessageFilters to retain the existing behavior.
pull/61/head
Jonathan Schwartz 2023-08-14 21:47:35 +00:00 committed by Kyle Schwarz
parent 41d6927496
commit 53e66b8772
3 changed files with 1234 additions and 1247 deletions

View File

@ -72,7 +72,7 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
packetLength = bytes[2]; // Long packets have a little endian length on bytes 3 and 4
packetLength |= bytes[3] << 8;
packet.network = Network((bytes[5] << 8) | bytes[4]); // Long packets have their netid stored as little endian on bytes 5 and 6
packet.network = Network(((bytes[5] << 8) | bytes[4]), false); // Long packets have their netid stored as little endian on bytes 5 and 6. Devices never send actual VNET IDs so we must not perform ID expansion here.
currentIndex += 4;
/* Long packets can't have a length less than 6, because that would indicate a negative payload size.

View File

@ -13,7 +13,7 @@ class MessageFilter {
public:
MessageFilter() {}
MessageFilter(Message::Type type) : includeInternalInAny(neomessagetype_t(type) & 0x8000), messageType(type) {}
MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid), netid) {}
MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid, false), netid) {} // Messages on the communication layer are never encoded as VNET ID + common ID, so skip the expansion step
MessageFilter(Network::Type type, Network::NetID net = Network::NetID::Any) : networkType(type), netid(net) {
// If a Network::Type::Internal is used, we want to also get internal Message::Types
// The NetID we want may be in there

View File

@ -10,6 +10,7 @@ typedef uint8_t neonettype_t;
#include <ostream>
#include <optional>
#include <tuple>
namespace icsneo {
@ -311,15 +312,14 @@ namespace icsneo {
VNET_A = 1,
VNET_B = 2,
};
/**
* So if you are passing in the offset from OFFSET_PLASMA_SLAVE1 or
* the offset from OFFSET_PLASMA_SLAVE2, return the vnet agnostic
* netid so caller can commonize handlers without caring about WHICH slave.
*/
static NetID OffsetToSimpleNetworkId(uint16_t offset)
{
switch (offset)
{
static NetID OffsetToSimpleNetworkId(uint16_t offset) {
switch(offset) {
default:
case 0:
return NetID::Device;
@ -425,66 +425,47 @@ namespace icsneo {
return NetID::LSFTCAN2;
}
}
static bool Within(neonetid_t value, neonetid_t min, neonetid_t max)
{
static bool Within(neonetid_t value, neonetid_t min, neonetid_t max) {
return ((min <= value) && (value < max));
}
static bool IdIsSlaveARange1(neonetid_t fullNetid)
{
static bool IdIsSlaveARange1(neonetid_t fullNetid) {
return Within(fullNetid, OFFSET_PLASMA_SLAVE1, OFFSET_PLASMA_SLAVE1 + COUNT_PLASMA_SLAVE);
}
static bool IdIsSlaveARange2(neonetid_t fullNetid)
{
static bool IdIsSlaveARange2(neonetid_t fullNetid) {
return Within(fullNetid, OFFSET_PLASMA_SLAVE1_RANGE2, OFFSET_PLASMA_SLAVE2_RANGE2);
}
static bool IdIsSlaveBRange1(neonetid_t fullNetid)
{
static bool IdIsSlaveBRange1(neonetid_t fullNetid) {
return Within(fullNetid, OFFSET_PLASMA_SLAVE2, OFFSET_PLASMA_SLAVE2 + COUNT_PLASMA_SLAVE);
}
static bool IdIsSlaveBRange2(neonetid_t fullNetid)
{
static bool IdIsSlaveBRange2(neonetid_t fullNetid) {
return Within(fullNetid, OFFSET_PLASMA_SLAVE2_RANGE2, OFFSET_PLASMA_SLAVE3_RANGE2);
}
static std::pair<VnetId, NetID> GetVnetAgnosticNetid(neonetid_t fullNetid)
{
static std::pair<VnetId, NetID> GetVnetAgnosticNetid(neonetid_t fullNetid) {
VnetId vnetId = VnetId::None;
NetID netId;
if (fullNetid < OFFSET_PLASMA_SLAVE1)
{
if(fullNetid < OFFSET_PLASMA_SLAVE1) {
netId = static_cast<NetID>(fullNetid);
}
else if (IdIsSlaveARange1(fullNetid))
{
} else if(IdIsSlaveARange1(fullNetid)) {
netId = OffsetToSimpleNetworkId(fullNetid - OFFSET_PLASMA_SLAVE1);
vnetId = VnetId::VNET_A;
}
else if (IdIsSlaveARange2(fullNetid))
{
} else if(IdIsSlaveARange2(fullNetid)) {
netId = static_cast<NetID>((fullNetid - OFFSET_PLASMA_SLAVE1_RANGE2));
vnetId = VnetId::VNET_A;
}
else if (IdIsSlaveBRange1(fullNetid))
{
} else if(IdIsSlaveBRange1(fullNetid)) {
netId = OffsetToSimpleNetworkId(fullNetid - OFFSET_PLASMA_SLAVE2);
vnetId = VnetId::VNET_B;
}
else if (IdIsSlaveBRange2(fullNetid))
{
} else if(IdIsSlaveBRange2(fullNetid)) {
netId = static_cast<NetID>((fullNetid - OFFSET_PLASMA_SLAVE2_RANGE2));
vnetId = VnetId::VNET_B;
}
else
{
} else {
netId = static_cast<NetID>(fullNetid);
}
return std::make_pair(vnetId, netId);
}
static const char* GetVnetIdString(VnetId vnetId)
{
switch (vnetId)
{
static const char* GetVnetIdString(VnetId vnetId) {
switch(vnetId) {
case VnetId::None:
return "None";
case VnetId::VNET_A:
@ -494,11 +475,12 @@ namespace icsneo {
}
return "Invalid VNET ID";
}
static Type GetTypeOfNetID(NetID netid) {
const auto [vnetId, commonNetId] = GetVnetAgnosticNetid((neonetid_t)netid);
(void)vnetId;
static Type GetTypeOfNetID(NetID netid, bool expand = true) {
if(expand) {
netid = GetVnetAgnosticNetid((neonetid_t)netid).second;
}
switch (commonNetId) {
switch(netid) {
case NetID::HSCAN:
case NetID::MSCAN:
case NetID::HSCAN2:
@ -610,11 +592,11 @@ namespace icsneo {
return Type::Other;
}
}
static const char* GetNetIDString(NetID netid) {
const auto [vnetId, commonNetId] = GetVnetAgnosticNetid((neonetid_t)netid);
(void)vnetId;
switch (commonNetId) {
static const char* GetNetIDString(NetID netid, bool expand = true) {
if(expand) {
netid = GetVnetAgnosticNetid((neonetid_t)netid).second;
}
switch(netid) {
case NetID::Device:
return "neoVI";
case NetID::HSCAN:
@ -1235,7 +1217,7 @@ namespace icsneo {
}
Network() { setValue(NetID::Invalid); }
Network(neonetid_t netid) { setValue(static_cast<NetID>(netid)); }
Network(neonetid_t netid, bool expand = true) { setValue(static_cast<NetID>(netid), expand); }
Network(NetID netid) { setValue(netid); }
Network(CoreMini cm) { setValue(GetNetIDFromCoreMiniNetwork(cm)); }
NetID getNetID() const { return value; }
@ -1254,12 +1236,17 @@ namespace icsneo {
Type type;
NetID commonNetId;
VnetId vnetId;
void setValue(NetID id) {
void setValue(NetID id, bool expand = true) {
value = id;
type = GetTypeOfNetID(value);
const auto vnetIdInfo = GetVnetAgnosticNetid((neonetid_t)id);
vnetId = vnetIdInfo.first;
commonNetId = vnetIdInfo.second;
// Constructor can optionally suppress the expansion of of the ID into a VNET slot and common ID. The communication decoder and packetizer require this for device responses.
type = GetTypeOfNetID(value, expand);
if(expand) {
std::tie(vnetId, commonNetId) = GetVnetAgnosticNetid((neonetid_t)id);
} else {
// Caller wanted to suppress VNET ID decoding.
vnetId = VnetId::None;
commonNetId = id;
}
}
};