Add retries into power control status commands

On first boot we're seeing an occasional miss of the
power status, but the match never being fired. This seems
to be caused by the sensors overwelming power control
by requesting too often. Add in a couple retries to
make sure we get the status.

Tested: On system with 100% production rate, cpu sensor
readings were valid

Change-Id: I19d3a342558db95c3a55ed8cb287df6629818c6a
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/Utils.cpp b/src/Utils.cpp
index f11a520..b8e4506 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -137,6 +137,72 @@
     return biosHasPost;
 }
 
+static void
+    getPowerStatus(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+                   size_t retries = 2)
+{
+    conn->async_method_call(
+        [conn, retries](boost::system::error_code ec,
+                        const std::variant<std::string>& state) {
+            if (ec)
+            {
+                if (retries)
+                {
+                    auto timer = std::make_shared<boost::asio::steady_timer>(
+                        conn->get_io_context());
+                    timer->expires_after(std::chrono::seconds(15));
+                    timer->async_wait(
+                        [timer, conn, retries](boost::system::error_code) {
+                            getPowerStatus(conn, retries - 1);
+                        });
+                    return;
+                }
+
+                // we commonly come up before power control, we'll capture the
+                // property change later
+                std::cerr << "error getting power status " << ec.message()
+                          << "\n";
+                return;
+            }
+            powerStatusOn =
+                boost::ends_with(std::get<std::string>(state), "Running");
+        },
+        power::busname, power::path, properties::interface, properties::get,
+        power::interface, power::property);
+}
+
+static void
+    getPostStatus(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+                  size_t retries = 2)
+{
+    conn->async_method_call(
+        [conn, retries](boost::system::error_code ec,
+                        const std::variant<std::string>& state) {
+            if (ec)
+            {
+                if (retries)
+                {
+                    auto timer = std::make_shared<boost::asio::steady_timer>(
+                        conn->get_io_context());
+                    timer->expires_after(std::chrono::seconds(15));
+                    timer->async_wait(
+                        [timer, conn, retries](boost::system::error_code) {
+                            getPostStatus(conn, retries - 1);
+                        });
+                    return;
+                }
+                // we commonly come up before power control, we'll capture the
+                // property change later
+                std::cerr << "error getting post status " << ec.message()
+                          << "\n";
+                return;
+            }
+            biosHasPost = std::get<std::string>(state) != "Inactive";
+        },
+        post::busname, post::path, properties::interface, properties::get,
+        post::interface, post::property);
+}
+
 void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
 {
     static boost::asio::steady_timer timer(conn->get_io_context());
@@ -203,34 +269,8 @@
             }
         });
 
-    conn->async_method_call(
-        [](boost::system::error_code ec,
-           const std::variant<std::string>& state) {
-            if (ec)
-            {
-                // we commonly come up before power control, we'll capture the
-                // property change later
-                return;
-            }
-            powerStatusOn =
-                boost::ends_with(std::get<std::string>(state), "Running");
-        },
-        power::busname, power::path, properties::interface, properties::get,
-        power::interface, power::property);
-
-    conn->async_method_call(
-        [](boost::system::error_code ec,
-           const std::variant<std::string>& state) {
-            if (ec)
-            {
-                // we commonly come up before power control, we'll capture the
-                // property change later
-                return;
-            }
-            biosHasPost = std::get<std::string>(state) != "Inactive";
-        },
-        post::busname, post::path, properties::interface, properties::get,
-        post::interface, post::property);
+    getPowerStatus(conn);
+    getPostStatus(conn);
 }
 
 // replaces limits if MinReading and MaxReading are found.