Add bios post checking support

Some sensors aren't available until after bios post
add support to check for post when needed.

Tested-by: SSB temp no longer asserted thresholds before
bios post.

Change-Id: I9251c2c501e082ef4bb0e9eb7909dc137771e120
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/Utils.hpp b/include/Utils.hpp
index 598662a..7c58e2a 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -35,6 +35,7 @@
                std::vector<std::filesystem::path>& foundPaths,
                unsigned int symlinkDepth = 1);
 bool isPowerOn(void);
+bool hasBiosPost(void);
 void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn);
 bool getSensorConfiguration(
     const std::string& type,
@@ -45,9 +46,10 @@
 void findLimits(std::pair<double, double>& limits,
                 const SensorBaseConfiguration* data);
 
-enum class PowerState : bool
+enum class PowerState
 {
     on,
+    biosPost,
     always
 };
 
@@ -82,3 +84,20 @@
         static_assert("Type Not Implemented");
     }
 }
+
+inline void setReadState(const std::string& str, PowerState& val)
+{
+
+    if (str == "On")
+    {
+        val = PowerState::on;
+    }
+    else if (str == "BiosPost")
+    {
+        val = PowerState::biosPost;
+    }
+    else if (str == "Always")
+    {
+        val = PowerState::always;
+    }
+}
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 9474caa..7f7f812 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -211,10 +211,7 @@
         {
             std::string powerState = variant_ns::visit(VariantToStringVisitor(),
                                                        findPowerOn->second);
-            if (powerState == "On")
-            {
-                readState = PowerState::on;
-            };
+            setReadState(powerState, readState);
         }
 
         sensors[sensorName] = std::make_unique<ADCSensor>(
diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
index 71d4a5b..af1f725 100644
--- a/src/IpmbSensor.cpp
+++ b/src/IpmbSensor.cpp
@@ -166,6 +166,10 @@
     {
         return;
     }
+    else if (readState == PowerState::biosPost && !hasBiosPost())
+    {
+        return;
+    }
     thresholds::checkThresholds(this);
 }
 
@@ -306,6 +310,16 @@
                         dbusConnection, io, name, pathPair.first, objectServer,
                         std::move(sensorThresholds), deviceAddress);
 
+                    auto findPowerState = entry.second.find("PowerState");
+
+                    if (findPowerState != entry.second.end())
+                    {
+                        std::string powerState = std::visit(
+                            VariantToStringVisitor(), findPowerState->second);
+
+                        setReadState(powerState, sensor->readState);
+                    }
+
                     if (sensorClass == "PxeBridgeTemp")
                     {
                         sensor->type = IpmbType::PXE1410CVR;
diff --git a/src/Utils.cpp b/src/Utils.cpp
index cd7baa4..4e7e029 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -30,6 +30,7 @@
     "/xyz/openbmc_project/Chassis/Control/Power0";
 
 static bool powerStatusOn = false;
+static bool biosHasPost = false;
 static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
 
 bool getSensorConfiguration(
@@ -118,16 +119,24 @@
     return powerStatusOn;
 }
 
+bool hasBiosPost(void)
+{
+    if (!powerMatch)
+    {
+        throw std::runtime_error("Power Match Not Created");
+    }
+    return biosHasPost;
+}
+
 void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
 {
-
     // create a match for powergood changes, first time do a method call to
     // cache the correct value
     std::function<void(sdbusplus::message::message & message)> eventHandler =
         [](sdbusplus::message::message& message) {
             std::string objectName;
-            boost::container::flat_map<std::string,
-                                       sdbusplus::message::variant<int32_t>>
+            boost::container::flat_map<
+                std::string, sdbusplus::message::variant<int32_t, bool>>
                 values;
             message.read(objectName, values);
             auto findPgood = values.find("pgood");
@@ -136,6 +145,12 @@
                 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(
                     findPgood->second);
             }
+            auto findPostComplete = values.find("post_complete");
+            if (findPostComplete != values.end())
+            {
+                biosHasPost = sdbusplus::message::variant_ns::get<bool>(
+                    findPostComplete->second);
+            }
         };
 
     powerMatch = std::make_unique<sdbusplus::bus::match::match>(
@@ -157,6 +172,20 @@
         },
         powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
         "Get", powerInterfaceName, "pgood");
+
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const sdbusplus::message::variant<int32_t>& postComplete) {
+            if (ec)
+            {
+                std::cerr << "Error getting initial post status\n";
+                return;
+            }
+            biosHasPost =
+                sdbusplus::message::variant_ns::get<int32_t>(postComplete);
+        },
+        powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
+        "Get", powerInterfaceName, "post_complete");
 }
 
 // replaces limits if MinReading and MaxReading are found.
@@ -180,4 +209,4 @@
         limits.second = sdbusplus::message::variant_ns::visit(
             VariantToDoubleVisitor(), maxFind->second);
     }
-}
\ No newline at end of file
+}