net-ipmid: Add sol conf change callback

Add a callback when the properties in interface
/xyz/openbmc_project/ipmi/sol/<eth name> was changed, update the sol
conf in sol manager.

Tested:
busctl set-property xyz.openbmc_project.Settings /xyz/openbmc_project/ipmi/sol/bond1 xyz.openbmc_project.Ipmi.SOL Enable b false

The callback was successfully called, and updated the sol manager conf.

Change-Id: Ie5949f6f701441275b849ade5ed4a50ea894b737
Signed-off-by: Jian Zhang <zhangjian.3032@bytedance.com>
diff --git a/main.cpp b/main.cpp
index eab9a2f..17fecfa 100644
--- a/main.cpp
+++ b/main.cpp
@@ -104,6 +104,9 @@
     command::registerGUIDChangeCallback();
     cache::guid = command::getSystemGUID();
 
+    // Register callback to update cache for sol conf change
+    sol::registerSolConfChangeCallbackHandler(channel);
+
     // Register the phosphor-net-ipmid session setup commands
     command::sessionSetupCommands();
 
diff --git a/sol/sol_manager.cpp b/sol/sol_manager.cpp
index 698159d..76f0bd8 100644
--- a/sol/sol_manager.cpp
+++ b/sol/sol_manager.cpp
@@ -26,6 +26,7 @@
 using namespace phosphor::logging;
 
 std::unique_ptr<sdbusplus::bus::match_t> matchPtrSOL(nullptr);
+std::unique_ptr<sdbusplus::bus::match_t> solConfPropertiesSignal(nullptr);
 
 void Manager::initConsoleSocket()
 {
@@ -268,4 +269,93 @@
     }
 }
 
+void procSolConfChange(sdbusplus::message::message& msg)
+{
+    using SolConfVariant = std::variant<bool, uint8_t>;
+    using SolConfProperties =
+        std::vector<std::pair<std::string, SolConfVariant>>;
+
+    std::string iface;
+    SolConfProperties properties;
+
+    try
+    {
+        msg.read(iface, properties);
+    }
+    catch (const std::exception& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "procSolConfChange get properties FAIL",
+            entry("ERROR=%s", e.what()));
+        return;
+    }
+
+    for (const auto& prop : properties)
+    {
+        if (prop.first == "Progress")
+        {
+            sol::Manager::get().progress = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "Enable")
+        {
+            sol::Manager::get().enable = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "ForceEncryption")
+        {
+            sol::Manager::get().forceEncrypt = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "ForceAuthentication")
+        {
+            sol::Manager::get().forceAuth = std::get<bool>(prop.second);
+        }
+        else if (prop.first == "Privilege")
+        {
+            sol::Manager::get().solMinPrivilege =
+                static_cast<session::Privilege>(std::get<uint8_t>(prop.second));
+        }
+        else if (prop.first == "AccumulateIntervalMS")
+        {
+            sol::Manager::get().accumulateInterval =
+                std::get<uint8_t>(prop.second) * sol::accIntervalFactor * 1ms;
+        }
+        else if (prop.first == "Threshold")
+        {
+            sol::Manager::get().sendThreshold = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "RetryCount")
+        {
+            sol::Manager::get().retryCount = std::get<uint8_t>(prop.second);
+        }
+        else if (prop.first == "RetryIntervalMS")
+        {
+            sol::Manager::get().retryInterval =
+                std::get<uint8_t>(prop.second) * sol::retryIntervalFactor * 1ms;
+        }
+    }
+}
+
+void registerSolConfChangeCallbackHandler(std::string channel)
+{
+    if (solConfPropertiesSignal == nullptr)
+    {
+        using namespace sdbusplus::bus::match::rules;
+        sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+        try
+        {
+            auto servicePath = solPath + channel;
+
+            solConfPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
+                bus, propertiesChangedNamespace(servicePath, solInterface),
+                procSolConfChange);
+        }
+        catch (const sdbusplus::exception_t& e)
+        {
+            log<level::ERR>("Failed to get service path in "
+                            "registerSolConfChangeCallbackHandler",
+                            entry("CHANNEL=%s", channel.c_str()));
+        }
+    }
+    return;
+}
+
 } // namespace sol
diff --git a/sol/sol_manager.hpp b/sol/sol_manager.hpp
index b266519..16a47fa 100644
--- a/sol/sol_manager.hpp
+++ b/sol/sol_manager.hpp
@@ -294,4 +294,7 @@
 /** @brief Callback method to close SOL sessions for SOL service change  */
 void registerSOLServiceChangeCallback();
 
+/** @brief Callback register method to SOL conf parameters change */
+void registerSolConfChangeCallbackHandler(std::string channel);
+
 } // namespace sol