Add retries into get sensor configuration

This adds retries into get sensor configuration and updates
fan sensor to use retries.

Tested:
- Sensors showed up as normal.
- Did a reboot bmc test where I saw retries get attempted
successfully.

Change-Id: I431f49c34b8e6376fee948b6ab06f426efcc5ba7
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/Utils.hpp b/include/Utils.hpp
index cc80f78..2c6ce9e 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -166,15 +166,82 @@
         dbusConnection(connection),
         callback(std::move(callbackFunc))
     {}
-    void getConfiguration(const std::vector<std::string>& interfaces)
+
+    void getPath(const std::string& path, const std::string& interface,
+                 const std::string& owner, size_t retries = 5)
     {
+        if (retries > 5)
+        {
+            retries = 5;
+        }
+        std::shared_ptr<GetSensorConfiguration> self = shared_from_this();
+
+        self->dbusConnection->async_method_call(
+            [self, path, interface, owner,
+             retries](const boost::system::error_code ec,
+                      boost::container::flat_map<std::string, BasicVariantType>&
+                          data) {
+                if (ec)
+                {
+                    std::cerr << "Error getting " << path << ": retries left"
+                              << retries - 1 << "\n";
+                    if (!retries)
+                    {
+                        return;
+                    }
+                    auto timer = std::make_shared<boost::asio::steady_timer>(
+                        self->dbusConnection->get_io_context());
+                    timer->expires_after(std::chrono::seconds(10));
+                    timer->async_wait([self, timer, path, interface, owner,
+                                       retries](boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            std::cerr << "Timer error!\n";
+                            return;
+                        }
+                        self->getPath(path, interface, owner, retries - 1);
+                    });
+                    return;
+                }
+
+                self->respData[path][interface] = std::move(data);
+            },
+            owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+            interface);
+    }
+
+    void getConfiguration(const std::vector<std::string>& interfaces,
+                          size_t retries = 0)
+    {
+        if (retries > 5)
+        {
+            retries = 5;
+        }
+
         std::shared_ptr<GetSensorConfiguration> self = shared_from_this();
         dbusConnection->async_method_call(
-            [self, interfaces](const boost::system::error_code ec,
-                               const GetSubTreeType& ret) {
+            [self, interfaces, retries](const boost::system::error_code ec,
+                                        const GetSubTreeType& ret) {
                 if (ec)
                 {
                     std::cerr << "Error calling mapper\n";
+                    if (!retries)
+                    {
+                        return;
+                    }
+                    auto timer = std::make_shared<boost::asio::steady_timer>(
+                        self->dbusConnection->get_io_context());
+                    timer->expires_after(std::chrono::seconds(10));
+                    timer->async_wait([self, timer, interfaces,
+                                       retries](boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            std::cerr << "Timer error!\n";
+                            return;
+                        }
+                        self->getConfiguration(interfaces, retries - 1);
+                    });
+
                     return;
                 }
                 for (const auto& [path, objDict] : ret)
@@ -198,23 +265,7 @@
                         {
                             continue;
                         }
-
-                        self->dbusConnection->async_method_call(
-                            [self, path, interface](
-                                const boost::system::error_code ec,
-                                boost::container::flat_map<
-                                    std::string, BasicVariantType>& data) {
-                                if (ec)
-                                {
-                                    std::cerr << "Error getting " << path
-                                              << "\n";
-                                    return;
-                                }
-                                self->respData[path][interface] =
-                                    std::move(data);
-                            },
-                            owner, path, "org.freedesktop.DBus.Properties",
-                            "GetAll", interface);
+                        self->getPath(path, interface, owner);
                     }
                 }
             },
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 73937cc..e8f1fff 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -87,7 +87,8 @@
         pwmSensors,
     std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
     const std::shared_ptr<boost::container::flat_set<std::string>>&
-        sensorsChanged)
+        sensorsChanged,
+    size_t retries = 0)
 {
 
     auto getter = std::make_shared<GetSensorConfiguration>(
@@ -377,7 +378,8 @@
             }
         }));
     getter->getConfiguration(
-        std::vector<std::string>{sensorTypes.begin(), sensorTypes.end()});
+        std::vector<std::string>{sensorTypes.begin(), sensorTypes.end()},
+        retries);
 }
 
 void createRedundancySensor(
@@ -475,7 +477,7 @@
                     return;
                 }
                 createSensors(io, objectServer, tachSensors, pwmSensors,
-                              systemBus, sensorsChanged);
+                              systemBus, sensorsChanged, 5);
             });
         };