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