From d9f16c1ee1b17aa3b7eb8d693a493ca7e04c9a6a Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 22 Apr 2025 16:46:48 +0800
Subject: [PATCH] Add retries to get inventory objects

Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
 src/DIMMTempSensorMain.cpp | 228 +++++++++++++++++++++----------------
 src/IntelCPUSensorMain.cpp |  54 ++++++---
 2 files changed, 171 insertions(+), 111 deletions(-)

diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index b8f002b..04e221b 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -35,7 +35,7 @@
 #include <string>
 #include <vector>
 
-constexpr const bool debug = false;
+constexpr const bool debug = true;
 constexpr const char* configInterface =
     "xyz.openbmc_project.Configuration.DIMMTemp";
 
@@ -46,109 +46,147 @@ static constexpr double minPowerReading = 0;
 
 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
 
-void createSensors(
+bool createSensors(
     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
-    boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>&
-        sensors,
+    boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>& sensors,
     std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
 {
     if (!dbusConnection)
     {
         std::cerr << "Connection not created\n";
-        return;
+        return false;
     }
 
-    dbusConnection->async_method_call(
-        [&io, &objectServer, &dbusConnection, &sensors](
-            boost::system::error_code ec, const ManagedObjectType& resp) {
-        if (ec)
+    ManagedObjectType resp;
+    resp.clear();
+    sdbusplus::message_t getManagedObjects =
+        dbusConnection->new_method_call(
+            entityManagerName, "/xyz/openbmc_project/inventory",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    try
+    {
+        sdbusplus::message_t reply =
+            dbusConnection->call(getManagedObjects);
+        reply.read(resp);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        std::cerr << "Error contacting entity manager\n";
+        return false;
+    }
+
+    for (const auto& pathPair : resp)
+    {
+        for (const auto& entry : pathPair.second)
+        {
+            if (entry.first != configInterface)
+            {
+                continue;
+            }
+            std::string name = loadVariant<std::string>(entry.second,
+                                                        "Name");
+
+            std::vector<thresholds::Threshold> sensorThresholds;
+            if (!parseThresholdsFromConfig(pathPair.second,
+                                            sensorThresholds))
+            {
+                std::cerr << "error populating thresholds for " << name
+                            << "\n";
+            }
+
+            float pollRate = loadVariant<double>(entry.second, "PollRate");
+            uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
+            uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
+            uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
+
+            /* calibration offset */
+            auto findCalibOffset = entry.second.find("Offset");
+            double calibOffset = 0;
+            if (findCalibOffset != entry.second.end())
+            {
+                calibOffset = std::visit(VariantToDoubleVisitor(),
+                                            findCalibOffset->second);
+            }
+
+            /* PowerState */
+            auto findPowerOn = entry.second.find("PowerState");
+            PowerState readState = PowerState::always;
+            if (findPowerOn != entry.second.end())
+            {
+                std::string powerState = std::visit(
+                    VariantToStringVisitor(), findPowerOn->second);
+                setReadState(powerState, readState);
+            }
+
+            if constexpr (debug)
+            {
+                std::cerr << "Configuration parsed for \n\t" << entry.first
+                            << "\n"
+                            << "with\n"
+                            << "\tName: " << name << "\n"
+                            << "\tBus: " << static_cast<int>(peciBus) << "\n"
+                            << "\tAddress: " << static_cast<int>(peciAddr)
+                            << "\n"
+                            << "\tDimmRank: " << static_cast<int>(dimmRank)
+                            << "\tOffset: " << calibOffset << "\n";
+            }
+
+            auto& sensor = sensors[name];
+            sensor = nullptr;
+
+            if (name.ends_with("_Temp"))
+            {
+                sensor = std::make_shared<DIMMTempSensor>(
+                    dbusConnection, io, name, pathPair.first, objectServer,
+                    std::move(sensorThresholds), maxTempReading,
+                    minTempReading, "temperature", sensor_paths::unitDegreesC,
+                    pollRate, readState, 0, peciBus, peciAddr, dimmRank);
+            }
+            else if (name.ends_with("_Power"))
+            {
+                sensor = std::make_shared<DIMMTempSensor>(
+                    dbusConnection, io, name, pathPair.first, objectServer,
+                    std::move(sensorThresholds), maxPowerReading,
+                    minPowerReading, "power", sensor_paths::unitWatts,
+                    pollRate, readState, 0, peciBus, peciAddr, dimmRank);
+            }
+
+            sensor->setupMatches(name);
+            sensor->init(name);
+        }
+    }
+    return true;
+}
+
+void startCreateSensors(
+    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+    boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>& sensors,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    boost::asio::steady_timer& filterTimer, int& retries)
+{
+    filterTimer.expires_after(std::chrono::seconds(3));
+    filterTimer.async_wait([&](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            return; // we're being canceled
+        }
+
+        if (createSensors(io, objectServer, sensors, dbusConnection))
         {
-            std::cerr << "Error contacting entity manager\n";
-            return;
+            retries = 0;
+            std::cout << "createSensors successed " << std::endl;
         }
-        for (const auto& pathPair : resp)
+        else
         {
-            for (const auto& entry : pathPair.second)
+            std::cout << "createSensors failed with retries " << retries << std::endl;
+            if (retries > 0)
             {
-                if (entry.first != configInterface)
-                {
-                    continue;
-                }
-                std::string name = loadVariant<std::string>(entry.second,
-                                                            "Name");
-
-                std::vector<thresholds::Threshold> sensorThresholds;
-                if (!parseThresholdsFromConfig(pathPair.second,
-                                               sensorThresholds))
-                {
-                    std::cerr << "error populating thresholds for " << name
-                              << "\n";
-                }
-
-                float pollRate = loadVariant<double>(entry.second, "PollRate");
-                uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
-                uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
-                uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
-
-                /* calibration offset */
-                auto findCalibOffset = entry.second.find("Offset");
-                double calibOffset = 0;
-                if (findCalibOffset != entry.second.end())
-                {
-                    calibOffset = std::visit(VariantToDoubleVisitor(),
-                                             findCalibOffset->second);
-                }
-
-                /* PowerState */
-                auto findPowerOn = entry.second.find("PowerState");
-                PowerState readState = PowerState::always;
-                if (findPowerOn != entry.second.end())
-                {
-                    std::string powerState = std::visit(
-                        VariantToStringVisitor(), findPowerOn->second);
-                    setReadState(powerState, readState);
-                }
-
-                if constexpr (debug)
-                {
-                    std::cerr << "Configuration parsed for \n\t" << entry.first
-                              << "\n"
-                              << "with\n"
-                              << "\tName: " << name << "\n"
-                              << "\tBus: " << static_cast<int>(peciBus) << "\n"
-                              << "\tAddress: " << static_cast<int>(peciAddr)
-                              << "\n"
-                              << "\tDimmRank: " << static_cast<int>(dimmRank)
-                              << "\tOffset: " << calibOffset << "\n";
-                }
-
-                auto& sensor = sensors[name];
-                sensor = nullptr;
-
-                if (name.ends_with("_Temp"))
-                {
-                    sensor = std::make_shared<DIMMTempSensor>(
-                        dbusConnection, io, name, pathPair.first, objectServer,
-                        std::move(sensorThresholds), maxTempReading,
-                        minTempReading, "temperature", sensor_paths::unitDegreesC,
-                        pollRate, readState, 0, peciBus, peciAddr, dimmRank);
-                }
-                else if (name.ends_with("_Power"))
-                {
-                    sensor = std::make_shared<DIMMTempSensor>(
-                        dbusConnection, io, name, pathPair.first, objectServer,
-                        std::move(sensorThresholds), maxPowerReading,
-                        minPowerReading, "power", sensor_paths::unitWatts,
-                        pollRate, readState, 0, peciBus, peciAddr, dimmRank);
-                }
-
-                sensor->setupMatches(name);
-                sensor->init(name);
+                retries--;
+                startCreateSensors(io, objectServer, sensors,
+                        dbusConnection, filterTimer, retries);
             }
         }
-    },
-        entityManagerName, "/xyz/openbmc_project/inventory",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    });
 }
 
 int main()
@@ -162,9 +200,11 @@ int main()
 
     boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>
         sensors;
+
     boost::asio::post(
         io, [&]() { createSensors(io, objectServer, sensors, systemBus); });
 
+    boost::asio::steady_timer filterTimer(io);
     boost::asio::steady_timer configTimer(io);
     std::function<void(sdbusplus::message::message&)> eventHandler =
         [&](sdbusplus::message::message&) {
@@ -181,11 +221,9 @@ int main()
                 std::cerr << "timer error\n";
                 return;
             }
-            createSensors(io, objectServer, sensors, systemBus);
-            if (sensors.empty())
-            {
-                std::cout << "Configuration not detected\n";
-            }
+
+            int retries = 20;
+            startCreateSensors(io, objectServer, sensors, systemBus, filterTimer, retries);
         });
     };
 
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index bdb6d25..bffba79 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -50,7 +50,7 @@
 #endif
 // clang-format on
 
-static constexpr bool debug = false;
+static constexpr bool debug = true;
 
 boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
     gCpuSensors;
@@ -718,6 +718,7 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
 {
     bool useCache = false;
     sensorConfigs.clear();
+    cpuConfigs.clear();
     // use new data the first time, then refresh
     for (const char* type : sensorTypes)
     {
@@ -834,6 +835,39 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
     return false;
 }
 
+void startGetCpuConfig(std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+    boost::container::flat_set<CPUConfig>& cpuConfigs, ManagedObjectType& sensorConfigs,
+    sdbusplus::asio::object_server& objectServer, boost::asio::steady_timer& filterTimer,
+    boost::asio::steady_timer& pingTimer, boost::asio::steady_timer& creationTimer,
+    boost::asio::io_context& io, int& retries)
+{
+    filterTimer.expires_after(std::chrono::seconds(3));
+    filterTimer.async_wait([&](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            return; // we're being canceled
+        }
+
+        if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
+        {
+            std::cout << "getCpuConfig successed " << std::endl;
+            retries = 0;
+            detectCpuAsync(pingTimer, creationTimer, io, objectServer,
+                           systemBus, cpuConfigs, sensorConfigs);
+        }
+        else
+        {
+            std::cout << "getCpuConfig failed with retries " << retries << std::endl;
+            if(retries > 0)
+            {
+                retries--;
+                startGetCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer,
+                    filterTimer, pingTimer, creationTimer, io, retries);
+            }
+        }
+    });
+}
+
 int main()
 {
     boost::asio::io_context io;
@@ -874,21 +908,9 @@ int main()
             std::cout << message.get_path() << " is changed\n";
         }
 
-        // this implicitly cancels the timer
-        filterTimer.expires_after(std::chrono::seconds(1));
-        filterTimer.async_wait([&](const boost::system::error_code& ec) {
-            if (ec == boost::asio::error::operation_aborted)
-            {
-                return; // we're being canceled
-            }
-
-            if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
-                             objectServer))
-            {
-                detectCpuAsync(pingTimer, creationTimer, io, objectServer,
-                               systemBus, cpuConfigs, sensorConfigs);
-            }
-        });
+        int retries = 20;
+        startGetCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer,
+            filterTimer, pingTimer, creationTimer, io, retries);
     };
 
     std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
-- 
2.34.1

