oem ibm: infrastructure for oem handlers

1. This commit adds the framework for an oem handler
which can be used by specific oem use-cases
for implementing various commands.

2. This commit adds implementation for getStateSensorReadings
and setStateEffecterStates commands for oem state sets.

3. Also adds implementation for inband code update.

Change-Id: Ib38a66ee381dd06b93f6a9313d51de1c23e6ee65
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index e425a9a..65998a7 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -222,7 +222,8 @@
            &address, sizeof(address));
 
     // Pass invalid payload length
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileIntoMemory(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -252,7 +253,8 @@
     // Initialise the file table with 2 valid file handles 0 & 1.
     auto& table = buildFileTable(fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -283,7 +285,8 @@
     using namespace pldm::filetable;
     auto& table = buildFileTable(fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -314,7 +317,8 @@
     using namespace pldm::filetable;
     auto& table = buildFileTable(fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -348,7 +352,8 @@
     using namespace pldm::filetable;
     auto& table = buildFileTable(fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -376,7 +381,8 @@
            &address, sizeof(address));
 
     // Pass invalid payload length
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.writeFileFromMemory(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -411,7 +417,8 @@
     // Initialise the file table with 2 valid file handles 0 & 1.
     auto& table = buildFileTable(fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.writeFileFromMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -443,7 +450,8 @@
     // Initialise the file table with 2 valid file handles 0 & 1.
     auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.writeFileFromMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -512,7 +520,8 @@
     request->operation_flag = opFlag;
     request->table_type = type;
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -535,7 +544,8 @@
     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
     // Pass invalid command payload length
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.getFileTable(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -557,7 +567,8 @@
     request->operation_flag = opFlag;
     request->table_type = type;
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
@@ -585,7 +596,8 @@
     auto& table = buildFileTable(fileTableConfig.c_str());
 
     // Invalid payload length
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFile(requestMsgPtr, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -635,7 +647,8 @@
     std::vector<char> buffer(length);
     stream.read(buffer.data(), length);
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
     auto response = reinterpret_cast<pldm_read_file_resp*>(
         responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -685,7 +698,8 @@
     request->length = length;
 
     // Invalid payload length
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.writeFile(requestMsgPtr, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -732,7 +746,8 @@
     request->length = length;
     memcpy(request->file_data, fileData.data(), fileData.size());
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
     auto response = reinterpret_cast<pldm_read_file_resp*>(
         responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -765,7 +780,8 @@
     request->length = 17;
     request->address = 0;
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.writeFileByTypeFromMemory(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
@@ -833,7 +849,8 @@
     request->length = 17;
     request->address = 0;
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileByTypeIntoMemory(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_read_write_file_by_type_memory_resp* resp =
@@ -871,7 +888,8 @@
     request->offset = 0;
     request->length = 13;
 
-    oem_ibm::Handler handler;
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+    oem_ibm::Handler handler(oemPlatformHandler.get());
     auto response = handler.readFileByType(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_read_write_file_by_type_resp* resp =
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
new file mode 100644
index 0000000..6b837dd
--- /dev/null
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -0,0 +1,103 @@
+#include "libpldm/entity.h"
+
+#include "common/utils.hpp"
+#include "libpldmresponder/event_parser.hpp"
+#include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
+#include "libpldmresponder/platform.hpp"
+#include "oem/ibm/libpldmresponder/inband_code_update.hpp"
+#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"
+#include "test/mocked_utils.hpp"
+
+#include <iostream>
+
+using namespace pldm::utils;
+using namespace pldm::responder;
+using namespace pldm::responder::pdr;
+using namespace pldm::responder::pdr_utils;
+using namespace pldm::responder::oem_ibm_platform;
+
+class MockCodeUpdate : public CodeUpdate
+{
+  public:
+    MockCodeUpdate(const pldm::utils::DBusHandler* dBusIntf) :
+        CodeUpdate(dBusIntf)
+    {}
+
+    MOCK_METHOD(void, setVersions, (), (override));
+};
+
+TEST(oemSetStateEffecterStatesHandler, testGoodRequest)
+{
+    uint16_t entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+    uint16_t stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
+    uint16_t entityInstance_ = 0;
+    uint8_t compSensorCnt_ = 1;
+
+    std::vector<get_sensor_state_field> stateField;
+
+    auto mockDbusHandler = std::make_unique<MockdBusHandler>();
+    std::unique_ptr<CodeUpdate> mockCodeUpdate =
+        std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
+    std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+
+    oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
+        mockDbusHandler.get(), mockCodeUpdate.get());
+
+    auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(stateField.size(), 1);
+    ASSERT_EQ(stateField[0].event_state, tSideNum);
+    ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_ENABLED);
+    ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_UNKNOWN);
+    ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN);
+
+    entityInstance_ = 1;
+
+    std::vector<get_sensor_state_field> stateField1;
+    rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+    ASSERT_EQ(stateField1.size(), 1);
+    ASSERT_EQ(stateField1[0].event_state, tSideNum);
+
+    entityInstance_ = 2;
+    rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+    ASSERT_EQ(stateField1[0].event_state, PLDM_SENSOR_UNKNOWN);
+
+    entityID_ = 40;
+    stateSetId_ = 50;
+    rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+    ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+
+    entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+    entityInstance_ = 0;
+    stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
+    compSensorCnt_ = 1;
+
+    std::vector<set_effecter_state_field> setEffecterStateField;
+    setEffecterStateField.push_back({PLDM_REQUEST_SET, pSideNum});
+
+    rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+        setEffecterStateField);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+
+    entityInstance_ = 2;
+    rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+        setEffecterStateField);
+
+    ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+
+    entityID_ = 34;
+    stateSetId_ = 99;
+    entityInstance_ = 0;
+    rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+        entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+        setEffecterStateField);
+    ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
+}