oem-ibm: create OEM PDRs for all OEM state sensors and
effecters

Created Sensors and effecters for Code update for the
Boot side and Firmware update State indication and
control.

root@rainier:/tmp# ./pldmtool platform GetPDR -d 22
nextRecordHandle: 23
responseCount: 30
recordHandle: 22
PDRHeaderVersion: 1
PDRType: State Effecter PDR(11)
recordChangeNumber: 0
dataLength: 16

PLDMTerminusHandle: 1
effecterID: 7
entityType: Virtual Machine Manager
entityInstanceNumber: 0
containerID: 0
effecterSemanticID: 0
effecterInit: noInit
effecterDescriptionPDR: false
compositeEffecterCount: 1
stateSetID: 32769
possibleStatesSize: 2
possibleStates: 1 2
root@rainier:/tmp# ./pldmtool platform GetPDR -d 23
nextRecordHandle: 24
responseCount: 30
recordHandle: 23
PDRHeaderVersion: 1
PDRType: State Effecter PDR(11)
recordChangeNumber: 0
dataLength: 16

PLDMTerminusHandle: 1
effecterID: 8
entityType: Virtual Machine Manager
entityInstanceNumber: 1
containerID: 0
effecterSemanticID: 0
effecterInit: noInit
effecterDescriptionPDR: false
compositeEffecterCount: 1
stateSetID: 32769
possibleStatesSize: 2
possibleStates: 1 2
root@rainier:/tmp# ./pldmtool platform GetPDR -d 24
nextRecordHandle: 25
responseCount: 30
recordHandle: 24
PDRHeaderVersion: 1
PDRType: State Effecter PDR(11)
recordChangeNumber: 0
dataLength: 16

PLDMTerminusHandle: 1
effecterID: 9
entityType: Virtual Machine Manager
entityInstanceNumber: 0
containerID: 0
effecterSemanticID: 0
effecterInit: noInit
effecterDescriptionPDR: false
compositeEffecterCount: 1
stateSetID: 32768
possibleStatesSize: 2
possibleStates: 1 2 3 4 5 6
root@rainier:/tmp# ./pldmtool platform GetPDR -d 25
nextRecordHandle: 26
responseCount: 28
recordHandle: 25
PDRHeaderVersion: 1
PDRType: State Sensor PDR(4)
recordChangeNumber: 0
dataLength: 14

PLDMTerminusHandle: 1
sensorID: 1
entityType: Virtual Machine Manager
entityInstanceNumber: 0
containerID: 0
sensorInit: noInit
sensorAuxiliaryNamesPDR: false
compositeSensorCount: 1
stateSetID: 32769
possibleStatesSize: 2
possibleStates: 1 2
root@rainier:/tmp# ./pldmtool platform GetPDR -d 26
nextRecordHandle: 27
responseCount: 28
recordHandle: 26
PDRHeaderVersion: 1
PDRType: State Sensor PDR(4)
recordChangeNumber: 0
dataLength: 14

PLDMTerminusHandle: 1
sensorID: 2
entityType: Virtual Machine Manager
entityInstanceNumber: 1
containerID: 0
sensorInit: noInit
sensorAuxiliaryNamesPDR: false
compositeSensorCount: 1
stateSetID: 32769
possibleStatesSize: 2
possibleStates: 1 2
root@rainier:/tmp# ./pldmtool platform GetPDR -d 27
nextRecordHandle: 0
responseCount: 28
recordHandle: 27
PDRHeaderVersion: 1
PDRType: State Sensor PDR(4)
recordChangeNumber: 0
dataLength: 14

PLDMTerminusHandle: 1
sensorID: 3
entityType: Virtual Machine Manager
entityInstanceNumber: 0
containerID: 0
sensorInit: noInit
sensorAuxiliaryNamesPDR: false
compositeSensorCount: 1
stateSetID: 32768
possibleStatesSize: 2
possibleStates: 1 2 3 4 5 6

Signed-off-by: Sagar Srinivas <sagar.srinivas@ibm.com>
Change-Id: I1dc39a549297241792cebc7812722447cce5762d
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index 52d0027..ca51366 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -62,6 +62,12 @@
         StateSetId stateSetId, CompositeCount compEffecterCnt,
         const std::vector<set_effecter_state_field>& stateField) = 0;
 
+    /** @brief Interface to generate the OEM PDRs
+     *
+     * @param[in] repo - instance of concrete implementation of Repo
+     */
+    virtual void buildOEMPDR(pdr_utils::Repo& repo) = 0;
+
     virtual ~Handler() = default;
 
   protected:
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 984d79b..24d1956 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -150,6 +150,11 @@
     {
         generateTerminusLocatorPDR(pdrRepo);
         generate(*dBusIntf, pdrJsonsDir, pdrRepo);
+        if (oemPlatformHandler != nullptr)
+        {
+            oemPlatformHandler->buildOEMPDR(pdrRepo);
+        }
+
         pdrCreated = true;
     }
 
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.hpp b/oem/ibm/libpldmresponder/file_io_by_type.hpp
index 502dbae..1aed02b 100644
--- a/oem/ibm/libpldmresponder/file_io_by_type.hpp
+++ b/oem/ibm/libpldmresponder/file_io_by_type.hpp
@@ -134,6 +134,5 @@
 
 std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
                                               uint32_t fileHandle);
-
 } // namespace responder
 } // namespace pldm
diff --git a/oem/ibm/libpldmresponder/inband_code_update.cpp b/oem/ibm/libpldmresponder/inband_code_update.cpp
index 489ad69..cdcf143 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.cpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.cpp
@@ -1,5 +1,8 @@
 #include "inband_code_update.hpp"
 
+#include "libpldm/entity.h"
+
+#include "libpldmresponder/pdr.hpp"
 #include "oem_ibm_handler.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
@@ -10,7 +13,6 @@
 
 namespace pldm
 {
-
 namespace responder
 {
 using namespace oem_ibm_platform;
diff --git a/oem/ibm/libpldmresponder/inband_code_update.hpp b/oem/ibm/libpldmresponder/inband_code_update.hpp
index 237a662..2ef638d 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.hpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "common/utils.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
 #include "libpldmresponder/platform.hpp"
 
 #include <string>
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 2e6bd4c..9c312c7 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -2,12 +2,12 @@
 
 #include "libpldm/entity.h"
 
+#include "libpldmresponder/pdr_utils.hpp"
+
 namespace pldm
 {
-
 namespace responder
 {
-
 namespace oem_ibm_platform
 {
 
@@ -23,7 +23,7 @@
     for (size_t i = 0; i < compSensorCnt; i++)
     {
         uint8_t sensorOpState{};
-        if (entityType == PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER &&
+        if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
             stateSetId == PLDM_OEM_IBM_BOOT_STATE)
         {
             sensorOpState = fetchBootSide(entityInstance, codeUpdate);
@@ -51,7 +51,7 @@
     {
         if (stateField[currState].set_request == PLDM_REQUEST_SET)
         {
-            if (entityType == PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER &&
+            if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
                 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
             {
                 rc = setBootSide(entityInstance, currState, stateField,
@@ -70,6 +70,119 @@
     return rc;
 }
 
+void buildAllCodeUpdateEffecterPDR(platform::Handler* platformHandler,
+                                   uint16_t entityInstance, uint16_t stateSetID,
+                                   pdr_utils::Repo& repo)
+{
+    size_t pdrSize = 0;
+    pdrSize = sizeof(pldm_state_effecter_pdr) +
+              sizeof(state_effecter_possible_states);
+    std::vector<uint8_t> entry{};
+    entry.resize(pdrSize);
+    pldm_state_effecter_pdr* pdr =
+        reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
+    if (!pdr)
+    {
+        std::cerr << "Failed to get record by PDR type, ERROR:"
+                  << PLDM_PLATFORM_INVALID_EFFECTER_ID << std::endl;
+    }
+    pdr->hdr.record_handle = 0;
+    pdr->hdr.version = 1;
+    pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
+    pdr->hdr.record_change_num = 0;
+    pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
+    pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
+    pdr->effecter_id = platformHandler->getNextEffecterId();
+    pdr->entity_type = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
+    pdr->entity_instance = entityInstance;
+    pdr->container_id = 0;
+    pdr->effecter_semantic_id = 0;
+    pdr->effecter_init = PLDM_NO_INIT;
+    pdr->has_description_pdr = false;
+    pdr->composite_effecter_count = 1;
+
+    auto* possibleStatesPtr = pdr->possible_states;
+    auto possibleStates =
+        reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
+    possibleStates->state_set_id = stateSetID;
+    possibleStates->possible_states_size = 2;
+    auto state =
+        reinterpret_cast<state_effecter_possible_states*>(possibleStates);
+    if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
+        state->states[0].byte = 6;
+    else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
+        state->states[0].byte = 126;
+    pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+    pdrEntry.data = entry.data();
+    pdrEntry.size = pdrSize;
+    repo.addRecord(pdrEntry);
+}
+
+void buildAllCodeUpdateSensorPDR(platform::Handler* platformHandler,
+                                 uint16_t entityInstance, uint16_t stateSetID,
+                                 pdr_utils::Repo& repo)
+{
+    size_t pdrSize = 0;
+    pdrSize =
+        sizeof(pldm_state_sensor_pdr) + sizeof(state_sensor_possible_states);
+    std::vector<uint8_t> entry{};
+    entry.resize(pdrSize);
+    pldm_state_sensor_pdr* pdr =
+        reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
+    if (!pdr)
+    {
+        std::cerr << "Failed to get record by PDR type, ERROR:"
+                  << PLDM_PLATFORM_INVALID_SENSOR_ID << std::endl;
+    }
+    pdr->hdr.record_handle = 0;
+    pdr->hdr.version = 1;
+    pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
+    pdr->hdr.record_change_num = 0;
+    pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
+    pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
+    pdr->sensor_id = platformHandler->getNextSensorId();
+    pdr->entity_type = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+    pdr->entity_instance = entityInstance;
+    pdr->container_id = 0;
+    pdr->sensor_init = PLDM_NO_INIT;
+    pdr->sensor_auxiliary_names_pdr = false;
+    pdr->composite_sensor_count = 1;
+
+    auto* possibleStatesPtr = pdr->possible_states;
+    auto possibleStates =
+        reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
+    possibleStates->state_set_id = stateSetID;
+    possibleStates->possible_states_size = 2;
+    auto state =
+        reinterpret_cast<state_sensor_possible_states*>(possibleStates);
+    if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
+        state->states[0].byte = 6;
+    else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
+        state->states[0].byte = 126;
+    pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+    pdrEntry.data = entry.data();
+    pdrEntry.size = pdrSize;
+    repo.addRecord(pdrEntry);
+}
+
+void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
+    pdr_utils::Repo& repo)
+{
+    buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
+                                  PLDM_OEM_IBM_BOOT_STATE, repo);
+    buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_1,
+                                  PLDM_OEM_IBM_BOOT_STATE, repo);
+    buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
+                                  PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
+
+    buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_0,
+                                PLDM_OEM_IBM_BOOT_STATE, repo);
+    buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_1,
+                                PLDM_OEM_IBM_BOOT_STATE, repo);
+    buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_0,
+                                PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
+}
+
 void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
     pldm::responder::platform::Handler* handler)
 {
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index 2d294f0..2220adb 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -6,16 +6,18 @@
 
 namespace pldm
 {
-
 namespace responder
 {
-
 namespace oem_ibm_platform
 {
 
 #define PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE 32768
 #define PLDM_OEM_IBM_BOOT_STATE 32769
 
+static constexpr auto PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE = 24577;
+constexpr uint16_t ENTITY_INSTANCE_0 = 0;
+constexpr uint16_t ENTITY_INSTANCE_1 = 1;
+
 class Handler : public oem_platform::Handler
 {
   public:
@@ -43,6 +45,32 @@
      */
     void setPlatformHandler(pldm::responder::platform::Handler* handler);
 
+    /** @brief Method to fetch the effecter ID of the code update PDRs
+     *
+     * @return platformHandler->getNextEffecterId() - returns the
+     *             effecter ID from the platform handler
+     */
+    uint16_t getNextEffecterId()
+    {
+        return platformHandler->getNextEffecterId();
+    }
+
+    /** @brief Method to fetch the sensor ID of the code update PDRs
+     *
+     * @return platformHandler->getNextSensorId() - returns the
+     *             Sensor ID from the platform handler
+     */
+    uint16_t getNextSensorId()
+    {
+        return platformHandler->getNextSensorId();
+    }
+
+    /** @brief Method to Generate the OEM PDRs
+     *
+     * @param[in] repo - instance of concrete implementation of Repo
+     */
+    void buildOEMPDR(pdr_utils::Repo& repo);
+
     ~Handler() = default;
 
     pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
index 6b837dd..7963313 100644
--- a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -29,7 +29,7 @@
 
 TEST(oemSetStateEffecterStatesHandler, testGoodRequest)
 {
-    uint16_t entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+    uint16_t entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
     uint16_t stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
     uint16_t entityInstance_ = 0;
     uint8_t compSensorCnt_ = 1;
@@ -73,7 +73,7 @@
         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
     ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
 
-    entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+    entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
     entityInstance_ = 0;
     stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
     compSensorCnt_ = 1;