Add helper functions to retrieve chassis paths/IDs

- Implemented chassis helper functions that retrieve all system chassis
and return them as a vector of chassis.

- Implemented a helper function to retrieve a chassis unique ID from the
  inventory manager.

- Implemented a helper function to retrieve the parent object path
  unique ID from the entity manager.

Tested:
  - Simulated several chassis in a system and verified all chassis
    within the vector.
  - Simulated chassis ID in the inventory manager and verified the
    chassis ID is as expected.
  - Simulated power supply path verified the parent ID retrieved from
    entity manager.

Change-Id: I1da380f05b71af2e629729ea5ea054e7573f2d58
Signed-off-by: Faisal Awada <faisal@us.ibm.com>
diff --git a/utility.cpp b/utility.cpp
index 0cee1bf..53fe965 100644
--- a/utility.cpp
+++ b/utility.cpp
@@ -30,6 +30,10 @@
 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
 
+constexpr auto DECORATOR_CHASSIS_ID =
+    "xyz.openbmc_project.Inventory.Decorator.Slot";
+constexpr auto CHASSIS_ID_PROPERTY = "SlotNumber";
+
 using json = nlohmann::json;
 
 std::string getService(const std::string& path, const std::string& interface,
@@ -207,6 +211,39 @@
     return paths;
 }
 
+std::vector<std::string> getChassisInventoryPaths(sdbusplus::bus_t& bus)
+{
+    std::vector<std::string> paths;
+    auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
+                                      MAPPER_INTERFACE, "GetSubTreePaths");
+    method.append(INVENTORY_OBJ_PATH);
+    method.append(0); // Depth 0 to search all
+    method.append(std::vector<std::string>({CHASSIS_IFACE}));
+    auto reply = bus.call(method);
+
+    reply.read(paths);
+    return paths;
+}
+
+uint64_t getChassisInventoryUniqueId(sdbusplus::bus_t& bus,
+                                     const std::string& path)
+{
+    uint32_t chassisId;
+    getProperty(DECORATOR_CHASSIS_ID, CHASSIS_ID_PROPERTY, path,
+                INVENTORY_MGR_IFACE, bus, chassisId);
+    return static_cast<uint64_t>(chassisId);
+}
+
+uint64_t getParentEMUniqueId(sdbusplus::bus_t& bus, const std::string& path)
+{
+    namespace fs = std::filesystem;
+    uint64_t chassisId;
+    fs::path fspath(path);
+    getProperty(DECORATOR_CHASSIS_ID, CHASSIS_ID_PROPERTY, fspath.parent_path(),
+                ENTITY_MGR_SERVICE, bus, chassisId);
+    return chassisId;
+}
+
 } // namespace util
 } // namespace power
 } // namespace phosphor
diff --git a/utility.hpp b/utility.hpp
index d2d9365..f4a7d73 100644
--- a/utility.hpp
+++ b/utility.hpp
@@ -22,6 +22,7 @@
 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
 constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
 constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
+constexpr auto ENTITY_MGR_SERVICE = "xyz.openbmc_project.EntityManager";
 
 using DbusPath = std::string;
 using DbusProperty = std::string;
@@ -230,6 +231,43 @@
  */
 std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus);
 
+/**
+ * @detail Get all chassis inventory paths from D-Bus
+ *
+ * @param[in] bus - D-Bus object
+ *
+ * @return The list of chassis inventory paths
+ */
+std::vector<std::string> getChassisInventoryPaths(sdbusplus::bus_t& bus);
+
+/**
+ * @brief Retrieve the chassis ID for the given D-Bus inventory path.
+ * Query the D-Bus interface for inventory object path and retrieve its unique
+ * ID (ID specified by SlotNumber)
+ *
+ * @param[in] bus - D-Bus object
+ * @param[in] path - The inventory manager D-Bus path for a chassis.
+ *
+ * @return uint64_t - Chassis unique ID
+ */
+uint64_t getChassisInventoryUniqueId(sdbusplus::bus_t& bus,
+                                     const std::string& path);
+/**
+ * @brief Retrieve the parent chassis unique ID from the Entity Manager.
+ * Given a D-Bus object path, this function extracts the parent path (board or
+ * chassis) and retrieve the chassis unique ID from Entity Manager.
+ *
+ * @param[in] bus - D-Bus object
+ * @param[in] path - The EntityManager D-Bus path for hardware within a chassis
+ * or board.
+ *
+ * @return uint64_t - Chassis unique ID
+ *
+ * @note This function assumes the parent object path contains property in
+ * Entity Manager.
+ */
+uint64_t getParentEMUniqueId(sdbusplus::bus_t& bus, const std::string& path);
+
 } // namespace util
 } // namespace power
 } // namespace phosphor