platform-mc: Add pldm entity inventory path

This commit exposes inventory path of each sensor to under the
entity's inventory path that it belongs to. In each path, the
xyz.openbmc_project.Inventory.Source.PLDM.Entity interface is
implemented with ContainerID, EntityInstanceNumber and EntityType
properties.

Signed-off-by: Chau Ly <chaul@amperecomputing.com>
Change-Id: Icf10349b7d272c6b050259151d71f21efedb0162
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index 25d420d..ab59154 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -15,6 +15,31 @@
 namespace platform_mc
 {
 
+inline bool NumericSensor::createInventoryPath(
+    const std::string& associationPath, const std::string& sensorName,
+    const uint16_t entityType, const uint16_t entityInstanceNum,
+    const uint16_t containerId)
+{
+    auto& bus = pldm::utils::DBusHandler::getBus();
+    std::string invPath = associationPath + "/" + sensorName;
+    try
+    {
+        entityIntf = std::make_unique<EntityIntf>(bus, invPath.c_str());
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error(
+            "Failed to create Entity interface for compact numeric sensor {PATH} error - {ERROR}",
+            "PATH", invPath, "ERROR", e);
+        return false;
+    }
+    entityIntf->entityType(entityType);
+    entityIntf->entityInstanceNumber(entityInstanceNum);
+    entityIntf->containerID(containerId);
+
+    return true;
+}
+
 NumericSensor::NumericSensor(
     const pldm_tid_t tid, const bool sensorDisabled,
     std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr, std::string& sensorName,
@@ -333,6 +358,12 @@
 
     hysteresis = unitModifier(conversionFormula(hysteresis));
 
+    if (!createInventoryPath(associationPath, sensorName, pdr->entity_type,
+                             pdr->entity_instance_num, pdr->container_id))
+    {
+        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+    }
+
     try
     {
         availabilityIntf =
@@ -587,6 +618,12 @@
 
     hysteresis = unitModifier(conversionFormula(hysteresis));
 
+    if (!createInventoryPath(associationPath, sensorName, pdr->entity_type,
+                             pdr->entity_instance, pdr->container_id))
+    {
+        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+    }
+
     try
     {
         availabilityIntf =
diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp
index 307f5e0..a55c51a 100644
--- a/platform-mc/numeric_sensor.hpp
+++ b/platform-mc/numeric_sensor.hpp
@@ -8,6 +8,7 @@
 
 #include <sdbusplus/server/object.hpp>
 #include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/Inventory/Source/PLDM/Entity/server.hpp>
 #include <xyz/openbmc_project/Metric/Value/server.hpp>
 #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
 #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
@@ -42,6 +43,8 @@
     sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability>;
 using AssociationDefinitionsInft = sdbusplus::server::object_t<
     sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
+using EntityIntf = sdbusplus::server::object_t<
+    sdbusplus::xyz::openbmc_project::Inventory::Source::PLDM::server::Entity>;
 
 /**
  * @brief NumericSensor
@@ -213,6 +216,21 @@
      */
     void updateThresholds();
 
+    /** @brief Create the sensor inventory path.
+     *
+     *  @param[in] associationPath - sensor association path
+     *  @param[in] sensorName - sensor name
+     *  @param[in] entityType - sensor PDR entity type
+     *  @param[in] entityInstanceNum - sensor PDR entity instance number
+     *  @param[in] containerId - sensor PDR entity container ID
+     *
+     *  @return True when success otherwise return False
+     */
+    inline bool createInventoryPath(
+        const std::string& associationPath, const std::string& sensorName,
+        const uint16_t entityType, const uint16_t entityInstanceNum,
+        const uint16_t containerId);
+
     std::unique_ptr<MetricIntf> metricIntf = nullptr;
     std::unique_ptr<ValueIntf> valueIntf = nullptr;
     std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr;
@@ -221,6 +239,7 @@
     std::unique_ptr<OperationalStatusIntf> operationalStatusIntf = nullptr;
     std::unique_ptr<AssociationDefinitionsInft> associationDefinitionsIntf =
         nullptr;
+    std::unique_ptr<EntityIntf> entityIntf = nullptr;
 
     /** @brief Amount of hysteresis associated with the sensor thresholds */
     double hysteresis;