From b31ac2adc02849b86fb38489b1d202df9d1b3a92 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski <cyril.danilevski@xfel.eu> Date: Wed, 26 Feb 2025 11:25:14 +0100 Subject: [PATCH 1/2] Handle invalid channel replies --- mpod.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/mpod.cpp b/mpod.cpp index 1190c9c..08e79ea 100644 --- a/mpod.cpp +++ b/mpod.cpp @@ -81,6 +81,9 @@ bool MPOD::message(const SNMP::Message *message) { case OID::OUTPUTSTATUS: { // OUTPUTSTATUS is defined in MIB as BITS but encoded as OCTETSTRING by MPOD OctetStringBER *status = static_cast<OctetStringBER *>(varbind->getValue()); + if (status->getLength() == 0) { + break; + } _on = status->getBit(0); _rampingUp = status->getBit(11); _rampingDown = status->getBit(12); @@ -88,31 +91,50 @@ bool MPOD::message(const SNMP::Message *message) { found++; break; case OID::OUTPUTMEASUREMENTSENSEVOLTAGE: - // Use private helper function to extract float value + if (varbind->getLength() != 25) { + break; + } _measurementSenseVoltage = getFloatFromVarBind(varbind); found++; break; case OID::OUTPUTMEASUREMENTCURRENT: + if (varbind->getLength() != 25) { + break; + } _measurementCurrent = getFloatFromVarBind(varbind); found++; break; case OID::OUTPUTSWITCH: // Use private helper function to extract integer value + Serial.print("Output Switch Length: "); + Serial.println(varbind->getLength()); _on = getIntegerFromVarBind(varbind); found++; break; case OID::OUTPUTVOLTAGE: + if (varbind->getLength() != 25) { + break; + } _voltage = getFloatFromVarBind(varbind); found++; break; case OID::OUTPUTCURRENT: + if (varbind->getLength() != 25) { + break; + } _current = getFloatFromVarBind(varbind); found++; break; case OID::OUTPUTVOLTAGERISERATE: + if (varbind->getLength() != 25) { + break; + } _voltageRiseRate = getFloatFromVarBind(varbind); found++; break; + default: + Serial.println(name); + break; } // Get the channel ID from the last value in the varbind name @@ -200,7 +222,7 @@ void onMessage(const SNMP::Message *message, const IPAddress remote, const uint1 Serial.print(mpod.getVoltageRiseRate()); Serial.println(" V/s"); } else { - Serial.println("Received non-MPOD traffic"); + Serial.println("Received non-MPOD traffic (invalid channel?)."); } } -- GitLab From 4d32668b2ba7d36c4f29b4be569d026c79f55c96 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski <cyril.danilevski@xfel.eu> Date: Wed, 26 Feb 2025 11:51:33 +0100 Subject: [PATCH 2/2] Handle invalid mpod responses in REST API --- mpod.cpp | 5 +++++ rest.cpp | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mpod.cpp b/mpod.cpp index 08e79ea..4ceb264 100644 --- a/mpod.cpp +++ b/mpod.cpp @@ -142,6 +142,11 @@ bool MPOD::message(const SNMP::Message *message) { // that far. const char *channel = strrchr(varbind->getName(), '.') + 1; _channel = atoi(channel); + + // MPOD SNMP channel 0 does not exist (starts from 1; U0 is 1). + // Mark the channel as 0 if invalid data was received. + // This can be used later to validate a sent request. + _channel = found ? _channel : 0; } // Return true if nodes found, that means this is a valid response from MPOD return found; diff --git a/rest.cpp b/rest.cpp index 2f1b0ae..e4bbea1 100644 --- a/rest.cpp +++ b/rest.cpp @@ -161,7 +161,7 @@ void sendSNMP() { if (output != NONE && channel != 0) { setChannelStateAndWait(&ipAddr, channel, output); - success = true; // validates input parameters, not MPOD status, reported separately + success = mpod.getChannel() ? true : false; } String http_msg = "{\n"; @@ -285,7 +285,12 @@ void pollMPODChannel() { delay(MPOD_UPDATE_LATENCY); snmp.loop(); // Force loop to update now - ret = mpod.toJSON(); + if (mpod.getChannel()) { + ret = mpod.toJSON(); + } else { + ret = "\"reason\": \"Invalid channel\""; + channel = 0; + } } String http_msg = "{\n"; -- GitLab