Mark sensor failed if non-functional

Use functional interface as well to determine if a
sensor has failed.

Tested: Saw fans boost when ME sensors failed by putting
ME in recovery mode

Change-Id: I4939d29d10c668c12464dadf40afe6669da8f051
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/dbus/dbuspassive.cpp b/dbus/dbuspassive.cpp
index 806ef40..02d1beb 100644
--- a/dbus/dbuspassive.cpp
+++ b/dbus/dbuspassive.cpp
@@ -117,7 +117,8 @@
             return true;
         }
     }
-    return _failed;
+
+    return _failed || !_functional;
 }
 
 void DbusPassive::setFailed(bool value)
@@ -125,6 +126,11 @@
     _failed = value;
 }
 
+void DbusPassive::setFunctional(bool value)
+{
+    _functional = value;
+}
+
 int64_t DbusPassive::getScale(void)
 {
     return _scale;
@@ -191,6 +197,17 @@
         }
         owner->setFailed(asserted);
     }
+    else if (msgSensor ==
+             "xyz.openbmc_project.State.Decorator.OperationalStatus")
+    {
+        auto functional = msgData.find("Functional");
+        if (functional == msgData.end())
+        {
+            return 0;
+        }
+        bool asserted = std::get<bool>(functional->second);
+        owner->setFunctional(asserted);
+    }
 
     return 0;
 }
diff --git a/dbus/dbuspassive.hpp b/dbus/dbuspassive.hpp
index f00a2ea..91733e9 100644
--- a/dbus/dbuspassive.hpp
+++ b/dbus/dbuspassive.hpp
@@ -52,6 +52,7 @@
 
     void setValue(double value);
     void setFailed(bool value);
+    void setFunctional(bool value);
     int64_t getScale(void);
     std::string getID(void);
     double getMax(void);
@@ -69,6 +70,7 @@
     double _max = 0;
     double _min = 0;
     bool _failed = false;
+    bool _functional = true;
 
     std::string path;
     std::shared_ptr<DbusPassiveRedundancy> redundancy;