oem:ibm :Implement SetFruRecordTable
The commit implements the setFruRecordTable command
and also updates the DBus property for the IBM cable cards
for which the host sends a setFruRecordTable command.
Tested: using pldmtool
Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
Change-Id: I70e4f85f627577d8ca1bc90447b10e9e2e8e7ccd
diff --git a/libpldmresponder/fru.cpp b/libpldmresponder/fru.cpp
index 8a04199..58c3316 100644
--- a/libpldmresponder/fru.cpp
+++ b/libpldmresponder/fru.cpp
@@ -429,6 +429,24 @@
return PLDM_SUCCESS;
}
+int FruImpl::setFRUTable(const std::vector<uint8_t>& fruData)
+{
+ auto record =
+ reinterpret_cast<const pldm_fru_record_data_format*>(fruData.data());
+ if (record)
+ {
+ if (oemFruHandler && record->record_type == PLDM_FRU_RECORD_TYPE_OEM)
+ {
+ auto rc = oemFruHandler->processOEMFRUTable(fruData);
+ if (!rc)
+ {
+ return PLDM_SUCCESS;
+ }
+ }
+ }
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+}
+
namespace fru
{
Response Handler::getFRURecordTableMetadata(const pldm_msg* request,
@@ -539,6 +557,44 @@
return response;
}
+Response Handler::setFRURecordTable(const pldm_msg* request,
+ size_t payloadLength)
+{
+ uint32_t transferHandle{};
+ uint8_t transferOpFlag{};
+ struct variable_field fruData;
+
+ auto rc = decode_set_fru_record_table_req(
+ request, payloadLength, &transferHandle, &transferOpFlag, &fruData);
+
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ Table table(fruData.ptr, fruData.ptr + fruData.length);
+ rc = impl.setFRUTable(table);
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ Response response(sizeof(pldm_msg_hdr) +
+ PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES);
+ struct pldm_msg* responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ rc = encode_set_fru_record_table_resp(
+ request->hdr.instance_id, PLDM_SUCCESS, 0 /* nextDataTransferHandle */,
+ response.size() - sizeof(pldm_msg_hdr), responsePtr);
+
+ if (rc != PLDM_SUCCESS)
+ {
+ return ccOnlyResponse(request, rc);
+ }
+
+ return response;
+}
+
} // namespace fru
} // namespace responder
diff --git a/libpldmresponder/fru.hpp b/libpldmresponder/fru.hpp
index da19d00..20bc509 100644
--- a/libpldmresponder/fru.hpp
+++ b/libpldmresponder/fru.hpp
@@ -1,6 +1,8 @@
#pragma once
#include "fru_parser.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
+#include "oem_handler.hpp"
#include "pldmd/handler.hpp"
#include <libpldm/fru.h>
@@ -59,13 +61,16 @@
* @param[in] entityTree - opaque pointer to the entity association tree
* @param[in] bmcEntityTree - opaque pointer to bmc's entity association
* tree
+ * @param[in] oemFruHandler - OEM fru handler
*/
FruImpl(const std::string& configPath,
const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
pldm_entity_association_tree* entityTree,
- pldm_entity_association_tree* bmcEntityTree) :
+ pldm_entity_association_tree* bmcEntityTree,
+ pldm::responder::oem_fru::Handler* oemFruHandler) :
parser(configPath, fruMasterJsonPath),
- pdrRepo(pdrRepo), entityTree(entityTree), bmcEntityTree(bmcEntityTree)
+ pdrRepo(pdrRepo), entityTree(entityTree), bmcEntityTree(bmcEntityTree),
+ oemFruHandler(oemFruHandler)
{}
/** @brief Total length of the FRU table in bytes, this includes the pad
@@ -188,6 +193,14 @@
*/
std::vector<uint8_t> tableResize();
+ /* @brief set FRU Record Table
+ *
+ * @param[in] fruData - the data of the fru
+ *
+ * @return PLDM completion code
+ */
+ int setFRUTable(const std::vector<uint8_t>& fruData);
+
private:
uint16_t nextRSI()
{
@@ -211,6 +224,7 @@
pldm_pdr* pdrRepo;
pldm_entity_association_tree* entityTree;
pldm_entity_association_tree* bmcEntityTree;
+ pldm::responder::oem_fru::Handler* oemFruHandler;
std::map<dbus::ObjectPath, pldm_entity_node*> objToEntityNode{};
@@ -240,8 +254,10 @@
Handler(const std::string& configPath,
const std::filesystem::path& fruMasterJsonPath, pldm_pdr* pdrRepo,
pldm_entity_association_tree* entityTree,
- pldm_entity_association_tree* bmcEntityTree) :
- impl(configPath, fruMasterJsonPath, pdrRepo, entityTree, bmcEntityTree)
+ pldm_entity_association_tree* bmcEntityTree,
+ pldm::responder::oem_fru::Handler* oemFruHandler) :
+ impl(configPath, fruMasterJsonPath, pdrRepo, entityTree, bmcEntityTree,
+ oemFruHandler)
{
handlers.emplace(
PLDM_GET_FRU_RECORD_TABLE_METADATA,
@@ -258,6 +274,11 @@
[this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
return this->getFRURecordByOption(request, payloadLength);
});
+ handlers.emplace(
+ PLDM_SET_FRU_RECORD_TABLE,
+ [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
+ return this->setFRURecordTable(request, payloadLength);
+ });
}
/** @brief Handler for Get FRURecordTableMetadata
@@ -309,6 +330,17 @@
Response getFRURecordByOption(const pldm_msg* request,
size_t payloadLength);
+ /** @brief Handler for SetFRURecordTable
+ *
+ * @param[in] request - Request message
+ * @param[in] payloadLength - Request payload length
+ *
+ * @return PLDM response message
+ */
+ Response setFRURecordTable(const pldm_msg* request, size_t payloadLength);
+
+ using Table = std::vector<uint8_t>;
+
private:
FruImpl impl;
};
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 156e3d1..50bafe3 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -46,6 +46,7 @@
'../oem/ibm/libpldmresponder/file_io_type_dump.cpp',
'../oem/ibm/libpldmresponder/file_io_type_cert.cpp',
'../oem/ibm/libpldmresponder/platform_oem_ibm.cpp',
+ '../oem/ibm/libpldmresponder/fru_oem_ibm.cpp',
'../oem/ibm/libpldmresponder/oem_ibm_handler.cpp',
'../oem/ibm/libpldmresponder/inband_code_update.cpp',
'../oem/ibm/requester/dbus_to_file_handler.cpp',
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index 3fcfeb0..542f823 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -118,6 +118,27 @@
} // namespace oem_platform
+namespace oem_fru
+{
+
+class Handler : public CmdHandler
+{
+ public:
+ Handler() {}
+
+ /** @brief Process OEM FRU record
+ *
+ * @param[in] fruData - the data of the fru
+ *
+ * @return success or failure
+ */
+ virtual int processOEMFRUTable(const std::vector<uint8_t>& fruData) = 0;
+
+ virtual ~Handler() = default;
+};
+
+} // namespace oem_fru
+
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/test/libpldmresponder_fru_test.cpp b/libpldmresponder/test/libpldmresponder_fru_test.cpp
index d654fca..2d7b7ec 100644
--- a/libpldmresponder/test/libpldmresponder_fru_test.cpp
+++ b/libpldmresponder/test/libpldmresponder_fru_test.cpp
@@ -117,7 +117,7 @@
pldm::responder::FruImpl mockedFruHandler(
FRU_JSONS_DIR, "./fru_jsons/fru_master/fru_master.json", pdrRepo.get(),
- entityTree.get(), bmcEntityTree.get());
+ entityTree.get(), bmcEntityTree.get(), nullptr);
pldm_entity systemEntity{0x2d01, 1, 0};
pldm_entity chassisEntity{0x2d, 1, 1};
@@ -170,7 +170,7 @@
InterfaceMap iface = {{"xyz.openbmc_project.Inventory.Item.Chassis", {}}};
pldm::responder::FruImpl mockedFruHandler(
FRU_JSONS_DIR, "./fru_jsons/fru_master/fru_master.json", pdrRepo.get(),
- entityTree.get(), bmcEntityTree.get());
+ entityTree.get(), bmcEntityTree.get(), nullptr);
// Good path
auto entityPtr = mockedFruHandler.getEntityByObjectPath(iface);