libpldmresponder: implement handler for GetPDR
This commit implements the GetPDR command as defined in DSP0248 v1.1.1.
Multipart PDR transfers are still not implemented.
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: Ic520a914e8228b723521151f4ba1eed947179047
diff --git a/test/Makefile.am b/test/Makefile.am
index 4b0acca..fbaa01f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -9,7 +9,8 @@
libpldm_bios_test \
libpldmresponder_bios_test \
libpldmresponder_pdr_state_effecter_test \
- libpldmresponder_bios_table_test
+ libpldmresponder_bios_table_test \
+ libpldmresponder_platform_test
if OEM_IBM
check_PROGRAMS += \
@@ -158,3 +159,19 @@
-lstdc++fs
libpldmresponder_bios_table_test_SOURCES = \
libpldmresponder_bios_table_test.cpp
+
+libpldmresponder_platform_test_CPPFLAGS = $(test_cppflags)
+libpldmresponder_platform_test_CXXFLAGS = $(test_cxxflags)
+libpldmresponder_platform_test_LDFLAGS = $(test_ldflags)
+libpldmresponder_platform_test_LDADD = \
+ $(top_builddir)/libpldm/libpldm_la-base.o \
+ $(top_builddir)/libpldm/libpldm_la-platform.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-pdr.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-effecters.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-platform.o \
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ $(SDBUSPLUS_LIBS) \
+ $(CODE_COVERAGE_LIBS) \
+ -lstdc++fs
+libpldmresponder_platform_test_SOURCES = libpldmresponder_platform_test.cpp
diff --git a/test/libpldmresponder_pdr_state_effecter_test.cpp b/test/libpldmresponder_pdr_state_effecter_test.cpp
index 24eea41..f763593 100644
--- a/test/libpldmresponder_pdr_state_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_state_effecter_test.cpp
@@ -11,7 +11,7 @@
{
using namespace pdr;
using namespace effecter::dbus_mapping;
- Repo& pdrRepo = get("./pdr_jsons/good");
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
// 2 entries
ASSERT_EQ(pdrRepo.numEntries(), 2);
@@ -100,8 +100,8 @@
TEST(GeneratePDR, testMalformedJson)
{
using namespace pdr;
- Repo& pdrRepo = get("./pdr_jsons/good");
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
ASSERT_EQ(pdrRepo.numEntries(), 2);
pdrRepo.makeEmpty();
- ASSERT_THROW(get("./pdr_jsons/malformed"), std::exception);
+ ASSERT_THROW(get("./pdr_jsons/state_effecter/malformed"), std::exception);
}
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
new file mode 100644
index 0000000..dd51e72
--- /dev/null
+++ b/test/libpldmresponder_platform_test.cpp
@@ -0,0 +1,173 @@
+#include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/platform.hpp"
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+using namespace pldm::responder;
+
+TEST(getPDR, testGoodPath)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t* start = request->payload;
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
+ *reqCount = 100;
+ using namespace pdr;
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+ ASSERT_EQ(pdrRepo.empty(), false);
+ auto response = getPDR(request, requestPayloadLength);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
+ start = responsePtr->payload;
+ start += sizeof(uint8_t);
+ uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
+ ASSERT_EQ(*nextRecordHandle, 2);
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
+ ASSERT_EQ(*recordCount != 0, true);
+ start += sizeof(uint16_t);
+ // Check a bit of the PDR common header
+ pldm_state_effecter_pdr* pdr =
+ reinterpret_cast<pldm_state_effecter_pdr*>(start);
+ ASSERT_EQ(pdr->hdr.record_handle, 1);
+ ASSERT_EQ(pdr->hdr.version, 1);
+}
+
+TEST(getPDR, testShortRead)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t* start = request->payload;
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
+ // Read 1 byte of PDR
+ *reqCount = 1;
+ using namespace pdr;
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+ ASSERT_EQ(pdrRepo.empty(), false);
+ auto response = getPDR(request, requestPayloadLength);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
+ start = responsePtr->payload;
+ start +=
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
+ ASSERT_EQ(*recordCount, 1);
+}
+
+TEST(getPDR, testBadRecordHandle)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t* start = request->payload;
+ uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
+ *recordHandle = 100000;
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
+ *reqCount = 1;
+ using namespace pdr;
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+ ASSERT_EQ(pdrRepo.empty(), false);
+ auto response = getPDR(request, requestPayloadLength);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
+}
+
+TEST(getPDR, testNoNextRecord)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t* start = request->payload;
+ uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
+ *recordHandle = 3;
+ using namespace pdr;
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+ ASSERT_EQ(pdrRepo.empty(), false);
+ auto response = getPDR(request, requestPayloadLength);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
+ start = responsePtr->payload;
+ start += sizeof(uint8_t);
+ uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
+ ASSERT_EQ(*nextRecordHandle, 0);
+}
+
+TEST(getPDR, testFindPDR)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t* start = request->payload;
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+ uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
+ *reqCount = 100;
+ using namespace pdr;
+ Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+ ASSERT_EQ(pdrRepo.empty(), false);
+ auto response = getPDR(request, requestPayloadLength);
+
+ // Let's try to find a PDR of type stateEffecter (= 11) and entity type =
+ // 100
+ bool found = false;
+ uint32_t handle = 0; // start asking for PDRs from recordHandle 0
+ uint32_t* recordHandle = nullptr;
+ while (!found)
+ {
+ start = request->payload;
+ recordHandle = reinterpret_cast<uint32_t*>(start);
+ *recordHandle = handle;
+ auto response = getPDR(request, requestPayloadLength);
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
+ start = responsePtr->payload;
+ start += sizeof(uint8_t);
+ uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
+ handle = *nextRecordHandle; // point to the next pdr in case current is
+ // not what we want
+ start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) +
+ sizeof(uint16_t);
+ pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
+ uint32_t intType = hdr->type;
+ std::cerr << "PDR next record handle " << handle << std::endl;
+ std::cerr << "PDR type " << intType << std::endl;
+ if (hdr->type == PLDM_STATE_EFFECTER_PDR)
+ {
+ pldm_state_effecter_pdr* pdr =
+ reinterpret_cast<pldm_state_effecter_pdr*>(start);
+ std::cerr << "PDR entity type " << pdr->entity_type << std::endl;
+ if (pdr->entity_type == 100)
+ {
+ found = true;
+ // Rest of the PDR can be accessed as need be
+ break;
+ }
+ }
+ if (!*nextRecordHandle) // no more records
+ {
+ break;
+ }
+ }
+ ASSERT_EQ(found, true);
+}
diff --git a/test/meson.build b/test/meson.build
index 93135fd..1ddb598 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -22,7 +22,8 @@
'libpldm_bios_test',
'libpldmresponder_bios_test',
'libpldmresponder_pdr_state_effecter_test',
- 'libpldmresponder_bios_table_test'
+ 'libpldmresponder_bios_table_test',
+ 'libpldmresponder_platform_test'
]
if get_option('oem-ibm').enabled()
diff --git a/test/pdr_jsons/good/11.json b/test/pdr_jsons/state_effecter/good/11.json
similarity index 100%
rename from test/pdr_jsons/good/11.json
rename to test/pdr_jsons/state_effecter/good/11.json
diff --git a/test/pdr_jsons/malformed/11.json b/test/pdr_jsons/state_effecter/malformed/11.json
similarity index 100%
rename from test/pdr_jsons/malformed/11.json
rename to test/pdr_jsons/state_effecter/malformed/11.json