Listener: Register correlated properties callback
This commit implements API to register callback for all interfaces in
correlated_properties.json.
```
Test:
1. Patch debug traces in the callback function.
2. On rainier 2s2u simics, do a busctl set-property on Decorator.Asset
PartNumber, com.ibm.ipzvpd.VINI PN of LCD Op Panel.
3. Observe vpd-manager logs and observe traces indicating callback is
getting triggered for above property changes.
```
Change-Id: I1ca2ae65724d8aa27424775fb1290a4139518644
Signed-off-by: Souvik Roy <souvikroyofficial10@gmail.com>
diff --git a/vpd-manager/include/listener.hpp b/vpd-manager/include/listener.hpp
index 9a6d627..734bf21 100644
--- a/vpd-manager/include/listener.hpp
+++ b/vpd-manager/include/listener.hpp
@@ -65,14 +65,15 @@
* JSON.
*/
void registerCorrPropCallBack(
- [[maybe_unused]] const std::string& i_correlatedPropJsonFile =
+ const std::string& i_correlatedPropJsonFile =
constants::correlatedPropJsonFile) noexcept;
/**
* @brief API to register properties changed callback.
*
* This API registers a properties changed callback for a specific interface
- * under a service.
+ * under a service by constructing a match object. This API also saves the
+ * constructed match object into map object map data member.
*
* @param[in] i_service - Service name.
* @param[in] i_interface - Interface name.
@@ -81,10 +82,8 @@
* @throw FirmwareException
*/
void registerPropChangeCallBack(
- [[maybe_unused]] const std::string& i_service,
- [[maybe_unused]] const std::string& i_interface,
- [[maybe_unused]] std::function<void(sdbusplus::message_t& i_msg)>
- i_callBackFunction);
+ const std::string& i_service, const std::string& i_interface,
+ std::function<void(sdbusplus::message_t& i_msg)> i_callBackFunction);
private:
/**
@@ -127,5 +126,8 @@
// Parsed correlated properties JSON.
nlohmann::json m_correlatedPropJson{};
+
+ // A map of {service name,{interface name,match object}}
+ types::MatchObjectMap m_matchObjectMap;
};
} // namespace vpd
diff --git a/vpd-manager/include/types.hpp b/vpd-manager/include/types.hpp
index 31d0085..fa44662 100644
--- a/vpd-manager/include/types.hpp
+++ b/vpd-manager/include/types.hpp
@@ -206,5 +206,9 @@
using InvalidRecordList = std::vector<InvalidRecordEntry>;
/* Map of inventory path -> Present property match object */
using FruPresenceMatchObjectMap = std::map<Path, std::shared_ptr<sdbusplus::bus::match::match>>;
+/* A map of interface to match object*/
+using MatchObjectInterfaceMap = std::map<std::string,std::shared_ptr<sdbusplus::bus::match::match>>;
+/* A map of service name to match object interface map*/
+using MatchObjectMap = std::map<std::string,MatchObjectInterfaceMap>;
} // namespace types
} // namespace vpd
diff --git a/vpd-manager/src/listener.cpp b/vpd-manager/src/listener.cpp
index bc9ef94..4084e0a 100644
--- a/vpd-manager/src/listener.cpp
+++ b/vpd-manager/src/listener.cpp
@@ -248,7 +248,7 @@
}
void Listener::registerCorrPropCallBack(
- [[maybe_unused]] const std::string& i_correlatedPropJsonFile) noexcept
+ const std::string& i_correlatedPropJsonFile) noexcept
{
try
{
@@ -259,9 +259,32 @@
throw JsonException("Failed to parse correlated properties JSON",
i_correlatedPropJsonFile);
}
- /* TODO:
- Parse correlated_properties JSON, and register callback for all
- interfaces under all services */
+
+ const nlohmann::json& l_serviceJsonObjectList =
+ m_correlatedPropJson.get_ref<const nlohmann::json::object_t&>();
+
+ // Iterate through all services in the correlated properties json
+ for (const auto& l_serviceJsonObject : l_serviceJsonObjectList.items())
+ {
+ const auto& l_serviceName = l_serviceJsonObject.key();
+
+ const nlohmann::json& l_correlatedIntfJsonObj =
+ m_correlatedPropJson[l_serviceName]
+ .get_ref<const nlohmann::json::object_t&>();
+
+ // register properties changed D-Bus signal callback
+ // for all interfaces under this service.
+ std::for_each(l_correlatedIntfJsonObj.items().begin(),
+ l_correlatedIntfJsonObj.items().end(),
+ [this, &l_serviceName = std::as_const(l_serviceName)](
+ const auto& i_interfaceJsonObj) {
+ registerPropChangeCallBack(
+ l_serviceName, i_interfaceJsonObj.key(),
+ [this](sdbusplus::message_t& i_msg) {
+ correlatedPropChangedCallBack(i_msg);
+ });
+ });
+ } // service loop
}
catch (const std::exception& l_ex)
{
@@ -273,17 +296,27 @@
}
void Listener::registerPropChangeCallBack(
- [[maybe_unused]] const std::string& i_service,
- [[maybe_unused]] const std::string& i_interface,
- [[maybe_unused]] std::function<void(sdbusplus::message_t& i_msg)>
- i_callBackFunction)
+ const std::string& i_service, const std::string& i_interface,
+ std::function<void(sdbusplus::message_t& i_msg)> i_callBackFunction)
{
try
{
- /*TODO:
- Create match object based on service name, interface and callback
- function.
- */
+ if (i_service.empty() || i_interface.empty())
+ {
+ throw std::runtime_error("Invalid service name or interface name");
+ }
+
+ std::shared_ptr<sdbusplus::bus::match::match> l_matchObj =
+ std::make_unique<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus_t&>(*m_asioConnection),
+ "type='signal',member='PropertiesChanged',"
+ "interface='org.freedesktop.DBus.Properties',"
+ "arg0='" +
+ i_interface + "'",
+ i_callBackFunction);
+
+ // save the match object in map
+ m_matchObjectMap[i_service][i_interface] = l_matchObj;
}
catch (const std::exception& l_ex)
{
@@ -301,9 +334,16 @@
throw DbusException("Error in reading property change signal.");
}
+ const std::string l_interface{i_msg.get_interface()};
+ const std::string l_objectPath{i_msg.get_path()};
+ const std::string l_signature{i_msg.get_signature()};
+
+ (void)l_interface;
+ (void)l_objectPath;
+ (void)l_signature;
+
/*TODO:
- 1. Extract interface, object path and property name from the message
- 2. Use correlated JSON to find target {object path, interface,
+ Use correlated JSON to find target {object path, interface,
property/properties} to update*/
}
catch (const std::exception& l_ex)