Utils: add optional callback for power state changes

Some systems require sensors to be instantiated and destroyed on host
power state transitions; this plumbing provides infrastructure for
dbus-sensors daemons to be notified on power state changes so they can
respond appropriately.

Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Change-Id: I2fc24c91e6d62bb3da71928ef0761760cc90e75f
diff --git a/src/Utils.cpp b/src/Utils.cpp
index da8cc67..60c05d6 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -395,7 +395,9 @@
         post::interface, post::property);
 }
 
-void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
+void setupPowerMatchCallback(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    std::function<void(PowerState type, bool state)>&& hostStatusCallback)
 {
     static boost::asio::steady_timer timer(conn->get_io_context());
     // create a match for powergood changes, first time do a method call to
@@ -410,7 +412,7 @@
         "type='signal',interface='" + std::string(properties::interface) +
             "',path='" + std::string(power::path) + "',arg0='" +
             std::string(power::interface) + "'",
-        [](sdbusplus::message_t& message) {
+        [hostStatusCallback](sdbusplus::message_t& message) {
         std::string objectName;
         boost::container::flat_map<std::string, std::variant<std::string>>
             values;
@@ -424,11 +426,13 @@
             {
                 timer.cancel();
                 powerStatusOn = false;
+                hostStatusCallback(PowerState::on, powerStatusOn);
                 return;
             }
             // on comes too quickly
             timer.expires_after(std::chrono::seconds(10));
-            timer.async_wait([](boost::system::error_code ec) {
+            timer.async_wait(
+                [hostStatusCallback](boost::system::error_code ec) {
                 if (ec == boost::asio::error::operation_aborted)
                 {
                     return;
@@ -439,6 +443,7 @@
                     return;
                 }
                 powerStatusOn = true;
+                hostStatusCallback(PowerState::on, powerStatusOn);
             });
         }
         });
@@ -448,7 +453,7 @@
         "type='signal',interface='" + std::string(properties::interface) +
             "',path='" + std::string(post::path) + "',arg0='" +
             std::string(post::interface) + "'",
-        [](sdbusplus::message_t& message) {
+        [hostStatusCallback](sdbusplus::message_t& message) {
         std::string objectName;
         boost::container::flat_map<std::string, std::variant<std::string>>
             values;
@@ -460,6 +465,7 @@
             biosHasPost = (value != "Inactive") &&
                           (value != "xyz.openbmc_project.State.OperatingSystem."
                                     "Status.OSStatus.Inactive");
+            hostStatusCallback(PowerState::biosPost, biosHasPost);
         }
         });
 
@@ -467,6 +473,11 @@
     getPostStatus(conn);
 }
 
+void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+    setupPowerMatchCallback(conn, [](PowerState, bool) {});
+}
+
 // replaces limits if MinReading and MaxReading are found.
 void findLimits(std::pair<double, double>& limits,
                 const SensorBaseConfiguration* data)