Allow the decoder to fail

pull/4/head
Paul Hollinsky 2018-10-18 14:06:58 -04:00
parent e5f1ba41b5
commit dd99f82324
7 changed files with 45 additions and 30 deletions

View File

@ -126,10 +126,12 @@ void Communication::readTask() {
if(impl->readWait(readBytes)) { if(impl->readWait(readBytes)) {
if(packetizer->input(readBytes)) { if(packetizer->input(readBytes)) {
for(auto& packet : packetizer->output()) { for(auto& packet : packetizer->output()) {
auto msg = decoder->decodePacket(packet); std::shared_ptr<Message> msg;
//std::cout << "Got packet for " << msg->network << ", calling " << messageCallbacks.size() << " callbacks" << std::endl; if(!decoder->decode(msg, packet))
for(auto& cb : messageCallbacks) { // We might have closed while reading or processing continue; // TODO Report an error to the user, we failed to decode this packet
if(!closing) {
for(auto& cb : messageCallbacks) {
if(!closing) { // We might have closed while reading or processing
cb.second.callIfMatch(msg); cb.second.callIfMatch(msg);
} }
} }

View File

@ -15,11 +15,11 @@ uint64_t Decoder::GetUInt64FromLEBytes(uint8_t* bytes) {
return ret; return ret;
} }
std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& packet) { bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) {
switch(packet->network.getType()) { switch(packet->network.getType()) {
case Network::Type::CAN: { case Network::Type::CAN: {
if(packet->data.size() < 24) if(packet->data.size() < 24)
break; // We would read garbage when interpereting the data return false;
HardwareCANPacket* data = (HardwareCANPacket*)packet->data.data(); HardwareCANPacket* data = (HardwareCANPacket*)packet->data.data();
auto msg = std::make_shared<CANMessage>(); auto msg = std::make_shared<CANMessage>();
@ -76,9 +76,7 @@ std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& pa
length = 64; length = 64;
break; break;
default: default:
length = 0; return false;
// TODO Flag an error
break;
} }
} }
@ -97,13 +95,14 @@ std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& pa
} }
} }
return msg; result = msg;
return true;
} }
case Network::Type::Internal: { case Network::Type::Internal: {
switch(packet->network.getNetID()) { switch(packet->network.getNetID()) {
case Network::NetID::Reset_Status: { case Network::NetID::Reset_Status: {
if(packet->data.size() < sizeof(HardwareResetStatusPacket)) if(packet->data.size() < sizeof(HardwareResetStatusPacket))
break; return false;
HardwareResetStatusPacket* data = (HardwareResetStatusPacket*)packet->data.data(); HardwareResetStatusPacket* data = (HardwareResetStatusPacket*)packet->data.data();
auto msg = std::make_shared<ResetStatusMessage>(); auto msg = std::make_shared<ResetStatusMessage>();
@ -125,10 +124,11 @@ std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& pa
msg->cmTooBig = data->status.cm_too_big; msg->cmTooBig = data->status.cm_too_big;
msg->hidUsbState = data->status.hidUsbState; msg->hidUsbState = data->status.hidUsbState;
msg->fpgaUsbState = data->status.fpgaUsbState; msg->fpgaUsbState = data->status.fpgaUsbState;
return msg; result = msg;
return true;
} }
default: default:
break; return false;
} }
} }
default: default:
@ -147,17 +147,17 @@ std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& pa
msg->hasPCBSerial = packet->data.size() >= 31; msg->hasPCBSerial = packet->data.size() >= 31;
if(msg->hasPCBSerial) if(msg->hasPCBSerial)
memcpy(msg->pcbSerial, packet->data.data() + 15, sizeof(msg->pcbSerial)); memcpy(msg->pcbSerial, packet->data.data() + 15, sizeof(msg->pcbSerial));
return msg; result = msg;
return true;
} }
break;
default: default:
auto msg = std::make_shared<Main51Message>(); auto msg = std::make_shared<Main51Message>();
msg->network = packet->network; msg->network = packet->network;
msg->command = Command(packet->data[0]); msg->command = Command(packet->data[0]);
msg->data.insert(msg->data.begin(), packet->data.begin() + 1, packet->data.end()); msg->data.insert(msg->data.begin(), packet->data.begin() + 1, packet->data.end());
return msg; result = msg;
return true;
} }
break;
} }
case Network::NetID::RED_OLDFORMAT: { case Network::NetID::RED_OLDFORMAT: {
/* So-called "old format" messages are a "new style, long format" wrapper around the old short messages. /* So-called "old format" messages are a "new style, long format" wrapper around the old short messages.
@ -169,18 +169,19 @@ std::shared_ptr<Message> Decoder::decodePacket(const std::shared_ptr<Packet>& pa
*/ */
uint16_t length = packet->data[0] | (packet->data[1] << 8); uint16_t length = packet->data[0] | (packet->data[1] << 8);
packet->network = Network(packet->data[2] & 0xF); packet->network = Network(packet->data[2] & 0xF);
//std::cout << "Got an old format packet, decoding against " << packet->network << std::endl;
packet->data.erase(packet->data.begin(), packet->data.begin() + 3); packet->data.erase(packet->data.begin(), packet->data.begin() + 3);
if(packet->data.size() != length) if(packet->data.size() != length)
packet->data.resize(length); packet->data.resize(length);
return decodePacket(packet); return decode(result, packet);
} }
} }
break;
} }
auto msg = std::make_shared<Message>(); return false;
msg->network = packet->network;
msg->data = packet->data; // auto msg = std::make_shared<Message>();
return msg; // msg->network = packet->network;
// msg->data = packet->data;
// result = msg;
// return true;
} }

View File

@ -16,7 +16,7 @@ namespace icsneo {
class Decoder { class Decoder {
public: public:
static uint64_t GetUInt64FromLEBytes(uint8_t* bytes); static uint64_t GetUInt64FromLEBytes(uint8_t* bytes);
std::shared_ptr<Message> decodePacket(const std::shared_ptr<Packet>& message); bool decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet);
private: private:
typedef uint16_t icscm_bitfield; typedef uint16_t icscm_bitfield;

View File

@ -102,7 +102,10 @@ void MultiChannelCommunication::readTask() {
if(packetizer->input(payloadBytes)) { if(packetizer->input(payloadBytes)) {
for(auto& packet : packetizer->output()) { for(auto& packet : packetizer->output()) {
auto msg = decoder->decodePacket(packet); std::shared_ptr<Message> msg;
if(!decoder->decode(msg, packet))
continue; // TODO Report an error to the user, we failed to decode this packet
for(auto& cb : messageCallbacks) { // We might have closed while reading or processing for(auto& cb : messageCallbacks) { // We might have closed while reading or processing
if(!closing) { if(!closing) {
cb.second.callIfMatch(msg); cb.second.callIfMatch(msg);

View File

@ -31,7 +31,10 @@ public:
for(auto& payload : foundDev.discoveryPackets) for(auto& payload : foundDev.discoveryPackets)
packetizer->input(payload); packetizer->input(payload);
for(auto& packet : packetizer->output()) { for(auto& packet : packetizer->output()) {
auto msg = decoder->decodePacket(packet); std::shared_ptr<Message> msg;
if(!decoder->decode(msg, packet))
continue; // We failed to decode this packet
if(!msg || msg->network.getNetID() != Network::NetID::Main51) if(!msg || msg->network.getNetID() != Network::NetID::Main51)
continue; // Not a message we care about continue; // Not a message we care about
auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg); auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg);

View File

@ -42,7 +42,10 @@ public:
for(auto& payload : foundDev.discoveryPackets) for(auto& payload : foundDev.discoveryPackets)
packetizer->input(payload); packetizer->input(payload);
for(auto& packet : packetizer->output()) { for(auto& packet : packetizer->output()) {
auto msg = decoder->decodePacket(packet); std::shared_ptr<Message> msg;
if(!decoder->decode(msg, packet))
continue; // We failed to decode this packet
if(!msg || msg->network.getNetID() != Network::NetID::Main51) if(!msg || msg->network.getNetID() != Network::NetID::Main51)
continue; // Not a message we care about continue; // Not a message we care about
auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg); auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg);

View File

@ -35,7 +35,10 @@ public:
for(auto& payload : foundDev.discoveryPackets) for(auto& payload : foundDev.discoveryPackets)
packetizer->input(payload); packetizer->input(payload);
for(auto& packet : packetizer->output()) { for(auto& packet : packetizer->output()) {
auto msg = decoder->decodePacket(packet); std::shared_ptr<Message> msg;
if(!decoder->decode(msg, packet))
continue; // We failed to decode this packet
if(!msg || msg->network.getNetID() != Network::NetID::Main51) if(!msg || msg->network.getNetID() != Network::NetID::Main51)
continue; // Not a message we care about continue; // Not a message we care about
auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg); auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg);