host-bmc: Implement Inventory Item interface

Adding support to host Inventory Item dbus interface.  PLDM hosts the
dbus interface based on the entity type.  The Inventory Item interface
is defined at [1].

Tested:
   Functional test passed

[1]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Inventory/Item.interface.yaml

Change-Id: Ifed3cc01d825a69d64afcffd8447f7c8d9387913
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/host-bmc/dbus/custom_dbus.cpp b/host-bmc/dbus/custom_dbus.cpp
index 08f9750..7a7e168 100644
--- a/host-bmc/dbus/custom_dbus.cpp
+++ b/host-bmc/dbus/custom_dbus.cpp
@@ -199,5 +199,29 @@
     availabilityState.at(path)->available(state);
 }
 
+void CustomDBus::updateItemPresentStatus(const std::string& path,
+                                         bool isPresent)
+{
+    if (!presentStatus.contains(path))
+    {
+        presentStatus.emplace(
+            path, std::make_unique<InventoryItem>(
+                      pldm::utils::DBusHandler::getBus(), path.c_str()));
+        std::filesystem::path ObjectPath(path);
+
+        // Hardcode the present dbus property to true
+        presentStatus.at(path)->present(true);
+
+        // Set the pretty name dbus property to the filename
+        // form the dbus path object
+        presentStatus.at(path)->prettyName(ObjectPath.filename());
+    }
+    else
+    {
+        // object is already created
+        presentStatus.at(path)->present(isPresent);
+    }
+}
+
 } // namespace dbus
 } // namespace pldm
diff --git a/host-bmc/dbus/custom_dbus.hpp b/host-bmc/dbus/custom_dbus.hpp
index e292462..e099712 100644
--- a/host-bmc/dbus/custom_dbus.hpp
+++ b/host-bmc/dbus/custom_dbus.hpp
@@ -9,6 +9,7 @@
 #include "cpu_core.hpp"
 #include "fabric_adapter.hpp"
 #include "fan.hpp"
+#include "inventory_item.hpp"
 #include "motherboard.hpp"
 #include "pcie_device.hpp"
 #include "pcie_slot.hpp"
@@ -190,11 +191,19 @@
      */
     void setAvailabilityState(const std::string& path, const bool& state);
 
+    /** @brief Set the Inventory Item property
+     *  @param[in] path - The object path
+     *  @param[in] bool - the presence of fru
+     */
+    void updateItemPresentStatus(const std::string& path, bool isPresent);
+
   private:
     std::unordered_map<ObjectPath, std::unique_ptr<Asset>> asset;
     std::unordered_map<ObjectPath, std::unique_ptr<Availability>>
         availabilityState;
     std::unordered_map<ObjectPath, std::unique_ptr<LocationIntf>> location;
+    std::unordered_map<ObjectPath, std::unique_ptr<InventoryItem>>
+        presentStatus;
     std::unordered_map<ObjectPath, std::unique_ptr<CPUCore>> cpuCore;
     std::unordered_map<ObjectPath, std::unique_ptr<ItemChassis>> chassis;
     std::unordered_map<ObjectPath, std::unique_ptr<PCIeDevice>> pcieDevice;
diff --git a/host-bmc/dbus/inventory_item.cpp b/host-bmc/dbus/inventory_item.cpp
new file mode 100644
index 0000000..a706220
--- /dev/null
+++ b/host-bmc/dbus/inventory_item.cpp
@@ -0,0 +1,32 @@
+#include "inventory_item.hpp"
+
+namespace pldm
+{
+namespace dbus
+{
+
+std::string InventoryItem::prettyName() const
+{
+    return sdbusplus::xyz::openbmc_project::Inventory::server::Item::
+        prettyName();
+}
+
+std::string InventoryItem::prettyName(std::string value)
+{
+    return sdbusplus::xyz::openbmc_project::Inventory::server::Item::prettyName(
+        value);
+}
+
+bool InventoryItem::present() const
+{
+    return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present();
+}
+
+bool InventoryItem::present(bool value)
+{
+    return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present(
+        value);
+}
+
+} // namespace dbus
+} // namespace pldm
diff --git a/host-bmc/dbus/inventory_item.hpp b/host-bmc/dbus/inventory_item.hpp
new file mode 100644
index 0000000..17699ee
--- /dev/null
+++ b/host-bmc/dbus/inventory_item.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <xyz/openbmc_project/Inventory/Item/server.hpp>
+
+#include <string>
+
+namespace pldm
+{
+namespace dbus
+{
+using ItemIntf = sdbusplus::server::object_t<
+    sdbusplus::xyz::openbmc_project::Inventory::server::Item>;
+
+class InventoryItem : public ItemIntf
+{
+  public:
+    InventoryItem() = delete;
+    ~InventoryItem() = default;
+    InventoryItem(const InventoryItem&) = delete;
+    InventoryItem& operator=(const InventoryItem&) = delete;
+    InventoryItem(InventoryItem&&) = delete;
+    InventoryItem& operator=(InventoryItem&&) = delete;
+
+    InventoryItem(sdbusplus::bus_t& bus, const std::string& objPath) :
+        ItemIntf(bus, objPath.c_str()), path(objPath)
+    {}
+
+    /** Get value of PrettyName */
+    std::string prettyName() const override;
+
+    /** Set value of PrettyName */
+    std::string prettyName(std::string value) override;
+
+    /** Get value of Present */
+    bool present() const override;
+
+    /** Set value of Present */
+    bool present(bool value) override;
+
+  private:
+    std::string path;
+};
+
+} // namespace dbus
+} // namespace pldm
diff --git a/host-bmc/host_pdr_handler.cpp b/host-bmc/host_pdr_handler.cpp
index 53ea526..e83495c 100644
--- a/host-bmc/host_pdr_handler.cpp
+++ b/host-bmc/host_pdr_handler.cpp
@@ -1135,6 +1135,11 @@
 #endif
 }
 
+void HostPDRHandler::setPresentPropertyStatus(const std::string& path)
+{
+    CustomDBus::getCustomDBus().updateItemPresentStatus(path, true);
+}
+
 void HostPDRHandler::setAvailabilityState(const std::string& path)
 {
     CustomDBus::getCustomDBus().setAvailabilityState(path, true);
@@ -1146,6 +1151,8 @@
 
     for (const auto& entity : objPathMap)
     {
+        // update the Present Property
+        setPresentPropertyStatus(entity.first);
         // Implement & update the Availability to true
         setAvailabilityState(entity.first);
 
diff --git a/host-bmc/host_pdr_handler.hpp b/host-bmc/host_pdr_handler.hpp
index 352dbf4..87da96c 100644
--- a/host-bmc/host_pdr_handler.hpp
+++ b/host-bmc/host_pdr_handler.hpp
@@ -268,6 +268,12 @@
      */
     void setPresenceFrus();
 
+    /** @brief Set the Present dbus Property
+     *  @param[in] path     - object path
+     *  @return
+     */
+    void setPresentPropertyStatus(const std::string& path);
+
     /** @brief Set the availabilty dbus Property
      *  @param[in] path     - object path
      */
diff --git a/host-bmc/test/meson.build b/host-bmc/test/meson.build
index 5f7ba7b..4ae286d 100644
--- a/host-bmc/test/meson.build
+++ b/host-bmc/test/meson.build
@@ -12,6 +12,7 @@
     '../dbus/cable.cpp',
     '../dbus/chassis.cpp',
     '../dbus/cpu_core.cpp',
+    '../dbus/inventory_item.cpp',
     '../dbus/pcie_device.cpp',
     '../dbus/pcie_slot.cpp',
 ]
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 58c0cec..14c8bb0 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -34,6 +34,7 @@
     '../host-bmc/dbus/cable.cpp',
     '../host-bmc/dbus/chassis.cpp',
     '../host-bmc/dbus/cpu_core.cpp',
+    '../host-bmc/dbus/inventory_item.cpp',
     '../host-bmc/utils.cpp',
     '../host-bmc/dbus/pcie_device.cpp',
     '../host-bmc/dbus/pcie_slot.cpp',