utils: Retrieval of managed objects of DBUS
This commit implements functionality to retrieve the managed object of a
specific DBUS service on a particular path. Additionally implements a
function template for inventory objects which efficiently enables
retrieval of managed object for Inventory Manager.
Tested: Added unit test cases for checking the return value.
Change-Id: Ide652f843db1623bdacebf3e269e03895bbb7f1a
Signed-off-by: Riya Dixit <riyadixitagra@gmail.com>
diff --git a/common/test/mocked_utils.hpp b/common/test/mocked_utils.hpp
index 71bc6e7..e42677c 100644
--- a/common/test/mocked_utils.hpp
+++ b/common/test/mocked_utils.hpp
@@ -22,6 +22,35 @@
} // namespace utils
} // namespace pldm
+class GetManagedEmptyObject
+{
+ public:
+ static pldm::utils::ObjectValueTree getManagedObj(const char* /*service*/,
+ const char* /*path*/)
+ {
+ return pldm::utils::ObjectValueTree{};
+ }
+};
+
+class GetManagedObject
+{
+ public:
+ static pldm::utils::ObjectValueTree getManagedObj(const char* /*service*/,
+ const char* /*path*/)
+ {
+ return pldm::utils::ObjectValueTree{
+ {sdbusplus::message::object_path("/foo/bar"),
+ {{"foo.bar",
+ {{"Functional", true},
+ {"Enabled", true},
+ {"PrettyName", "System"},
+ {"Present", true},
+ {"SerialNumber", "abc123z"},
+ {"Model", "1234 - 00Z"},
+ {"SubModel", "S0"}}}}}};
+ }
+};
+
class MockdBusHandler : public pldm::utils::DBusHandler
{
public:
diff --git a/common/test/pldm_utils_test.cpp b/common/test/pldm_utils_test.cpp
index 549e289..93cf335 100644
--- a/common/test/pldm_utils_test.cpp
+++ b/common/test/pldm_utils_test.cpp
@@ -1,4 +1,5 @@
#include "common/utils.hpp"
+#include "mocked_utils.hpp"
#include <libpldm/platform.h>
@@ -6,6 +7,28 @@
using namespace pldm::utils;
+TEST(GetInventoryObjects, testForEmptyObject)
+{
+ ObjectValueTree result =
+ DBusHandler::getInventoryObjects<GetManagedEmptyObject>();
+ EXPECT_TRUE(result.empty());
+}
+
+TEST(GetInventoryObjects, testForObject)
+{
+ std::string path = "/foo/bar";
+ std::string service = "foo.bar";
+ auto result = DBusHandler::getInventoryObjects<GetManagedObject>();
+ EXPECT_EQ(result[path].begin()->first, service);
+ auto function =
+ std::get<bool>(result[path][service][std::string("Functional")]);
+ auto model =
+ std::get<std::string>(result[path][service][std::string("Model")]);
+ EXPECT_FALSE(result.empty());
+ EXPECT_TRUE(function);
+ EXPECT_EQ(model, std::string("1234 - 00Z"));
+}
+
TEST(decodeDate, testGooduintToDate)
{
uint64_t data = 20191212115959;
diff --git a/common/utils.cpp b/common/utils.cpp
index 7e43b49..eee9f43 100644
--- a/common/utils.cpp
+++ b/common/utils.cpp
@@ -563,6 +563,16 @@
return bus.call(method, dbusTimeout).unpack<PropertyValue>();
}
+ObjectValueTree DBusHandler::getManagedObj(const char* service,
+ const char* rootPath)
+{
+ auto& bus = DBusHandler::getBus();
+ auto method = bus.new_method_call(service, rootPath,
+ "org.freedesktop.DBus.ObjectManager",
+ "GetManagedObjects");
+ return bus.call(method).unpack<ObjectValueTree>();
+}
+
PropertyValue jsonEntryToDbusVal(std::string_view type,
const nlohmann::json& value)
{
diff --git a/common/utils.hpp b/common/utils.hpp
index e940265..2d3fb7f 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -14,6 +14,7 @@
#include <nlohmann/json.hpp>
#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Inventory/Manager/client.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>
#include <deque>
@@ -182,8 +183,12 @@
return bcd;
}
+using inventoryManager =
+ sdbusplus::client::xyz::openbmc_project::inventory::Manager<>;
+
constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
+constexpr auto inventoryPath = "/xyz/openbmc_project/inventory";
struct DBusMapping
{
@@ -195,7 +200,8 @@
using PropertyValue =
std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
- uint64_t, double, std::string, std::vector<std::string>>;
+ uint64_t, double, std::string, std::vector<uint8_t>,
+ std::vector<std::string>>;
using DbusProp = std::string;
using DbusChangedProps = std::map<DbusProp, PropertyValue>;
using DBusInterfaceAdded = std::vector<
@@ -209,6 +215,7 @@
using GetSubTreeResponse = std::vector<std::pair<ObjectPath, MapperServiceMap>>;
using PropertyMap = std::map<std::string, PropertyValue>;
using InterfaceMap = std::map<std::string, PropertyMap>;
+using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
/**
* @brief The interface for DBusHandler
@@ -328,6 +335,34 @@
*/
void setDbusProperty(const DBusMapping& dBusMap,
const PropertyValue& value) const override;
+
+ /** @brief This function retrieves the properties of an object managed
+ * by the specified D-Bus service located at the given object path.
+ *
+ * @param[in] service - The D-Bus service providing the managed object
+ * @param[in] value - The object path of the managed object
+ *
+ * @return A hierarchical structure representing the properties of the
+ * managed object.
+ * @throw sdbusplus::exception::exception when it fails
+ */
+ static ObjectValueTree getManagedObj(const char* service, const char* path);
+
+ /** @brief Retrieve the inventory objects managed by a specified class.
+ * The retrieved inventory objects are cached statically
+ * and returned upon subsequent calls to this function.
+ *
+ * @tparam ClassType - The class type that manages the inventory objects.
+ *
+ * @return A reference to the cached inventory objects.
+ */
+ template <typename ClassType>
+ static auto& getInventoryObjects()
+ {
+ static ObjectValueTree object = ClassType::getManagedObj(
+ inventoryManager::interface, inventoryPath);
+ return object;
+ }
};
/** @brief Fetch parent D-Bus object based on pathname
diff --git a/libpldmresponder/fru.cpp b/libpldmresponder/fru.cpp
index 632489c..a9ef613 100644
--- a/libpldmresponder/fru.cpp
+++ b/libpldmresponder/fru.cpp
@@ -145,18 +145,12 @@
}
fru_parser::DBusLookupInfo dbusInfo;
- // Read the all the inventory D-Bus objects
- auto& bus = pldm::utils::DBusHandler::getBus();
- dbus::ObjectValueTree objects;
try
{
dbusInfo = parser.inventoryLookup();
- auto method = bus.new_method_call(
- std::get<0>(dbusInfo).c_str(), std::get<1>(dbusInfo).c_str(),
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- auto reply = bus.call(method, dbusTimeout);
- reply.read(objects);
+ objects = pldm::utils::DBusHandler::getInventoryObjects<
+ pldm::utils::DBusHandler>();
}
catch (const std::exception& e)
{
diff --git a/libpldmresponder/fru.hpp b/libpldmresponder/fru.hpp
index 20bc509..40a1517 100644
--- a/libpldmresponder/fru.hpp
+++ b/libpldmresponder/fru.hpp
@@ -24,9 +24,9 @@
namespace dbus
{
-using Value =
- std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
- uint64_t, double, std::string, std::vector<uint8_t>>;
+using Value = std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+ int64_t, uint64_t, double, std::string,
+ std::vector<uint8_t>, std::vector<std::string>>;
using PropertyMap = std::map<Property, Value>;
using InterfaceMap = std::map<Interface, PropertyMap>;
using ObjectValueTree = std::map<sdbusplus::message::object_path, InterfaceMap>;
@@ -225,6 +225,7 @@
pldm_entity_association_tree* entityTree;
pldm_entity_association_tree* bmcEntityTree;
pldm::responder::oem_fru::Handler* oemFruHandler;
+ dbus::ObjectValueTree objects;
std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
diff --git a/oem/ibm/libpldmresponder/file_io_type_dump.cpp b/oem/ibm/libpldmresponder/file_io_type_dump.cpp
index f1c6bec..f3394a3 100644
--- a/oem/ibm/libpldmresponder/file_io_type_dump.cpp
+++ b/oem/ibm/libpldmresponder/file_io_type_dump.cpp
@@ -46,14 +46,11 @@
static constexpr auto DUMP_MANAGER_BUSNAME =
"xyz.openbmc_project.Dump.Manager";
static constexpr auto DUMP_MANAGER_PATH = "/xyz/openbmc_project/dump";
- static constexpr auto OBJECT_MANAGER_INTERFACE =
- "org.freedesktop.DBus.ObjectManager";
- auto& bus = pldm::utils::DBusHandler::getBus();
// Stores the current resource dump entry path
std::string curResDumpEntryPath{};
- dbus::ObjectValueTree objects;
+ ObjectValueTree objects;
// Select the dump entry interface for system dump or resource dump
DumpEntryInterface dumpEntryIntf = systemDumpEntry;
if ((dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP) ||
@@ -64,12 +61,8 @@
try
{
- auto method =
- bus.new_method_call(DUMP_MANAGER_BUSNAME, DUMP_MANAGER_PATH,
- OBJECT_MANAGER_INTERFACE, "GetManagedObjects");
-
- auto reply = bus.call(method, dbusTimeout);
- reply.read(objects);
+ objects = pldm::utils::DBusHandler::getManagedObj(DUMP_MANAGER_BUSNAME,
+ DUMP_MANAGER_PATH);
}
catch (const sdbusplus::exception_t& e)
{
diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp
index 1a8a6a9..a962228 100644
--- a/requester/mctp_endpoint_discovery.cpp
+++ b/requester/mctp_endpoint_discovery.cpp
@@ -20,15 +20,12 @@
"/xyz/openbmc_project/mctp"),
std::bind_front(&MctpDiscovery::dicoverEndpoints, this))
{
- dbus::ObjectValueTree objects;
+ pldm::utils::ObjectValueTree objects;
try
{
- auto method = bus.new_method_call(
- "xyz.openbmc_project.MCTP", "/xyz/openbmc_project/mctp",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- auto reply = bus.call(method, dbusTimeout);
- reply.read(objects);
+ objects = pldm::utils::DBusHandler::getManagedObj(MCTPService,
+ MCTPPath);
}
catch (const std::exception& e)
{
diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp
index 7fbe069..de3a6bd 100644
--- a/requester/mctp_endpoint_discovery.hpp
+++ b/requester/mctp_endpoint_discovery.hpp
@@ -7,6 +7,9 @@
namespace pldm
{
+constexpr auto MCTPService = "xyz.openbmc_project.MCTP";
+constexpr auto MCTPPath = "/xyz/openbmc_project/mctp";
+
class MctpDiscovery
{
public: