Handle FRU records from host
- Get FRU record table from host and traverse the entity structure
from the FRU record set PDR, and create D-Bus object.
- When the FRU field type is a PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE
, the location code is used to populate the
xyz.openbmc_project.Inventory.Decorator.LocationCode D-Bus
interface for the corresponding FRU.
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I482c4d371f76b4881109ef420dfd9543e1aa810b
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index ad4207b..7de2cf2 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -26,6 +26,7 @@
'../host-bmc/dbus_to_event_handler.cpp',
'../host-bmc/dbus_to_host_effecters.cpp',
'../host-bmc/host_condition.cpp',
+ '../host-bmc/custom_dbus.cpp',
'event_parser.cpp'
]
diff --git a/libpldmresponder/pdr_utils.cpp b/libpldmresponder/pdr_utils.cpp
index 7e5e491..06832a1 100644
--- a/libpldmresponder/pdr_utils.cpp
+++ b/libpldmresponder/pdr_utils.cpp
@@ -1,3 +1,5 @@
+#include "libpldm/fru.h"
+
#include "pdr.hpp"
#include <libpldm/platform.h>
@@ -16,6 +18,15 @@
{
namespace pdr_utils
{
+// Refer: DSP0257_1.0.0 Table 2
+// 7: uint16_t(FRU Record Set Identifier), uint8_t(FRU Record Type),
+// uint8_t(Number of FRU fields), uint8_t(Encoding Type for FRU fields),
+// uint8_t(FRU Field Type), uint8_t(FRU Field Length)
+static constexpr uint8_t fruRecordDataFormatLength = 7;
+
+// // 2: 1byte FRU Field Type, 1byte FRU Field Length
+static constexpr uint8_t fruFieldTypeLength = 2;
+
pldm_pdr* Repo::getPdr() const
{
return repo;
@@ -196,6 +207,58 @@
std::move(sensorInfo));
}
+std::vector<FruRecordDataFormat> parseFruRecordTable(const uint8_t* fruData,
+ size_t fruLen)
+{
+ // Refer: DSP0257_1.0.0 Table 2
+ // 7: uint16_t(FRU Record Set Identifier), uint8_t(FRU Record Type),
+ // uint8_t(Number of FRU fields), uint8_t(Encoding Type for FRU fields),
+ // uint8_t(FRU Field Type), uint8_t(FRU Field Length)
+ if (fruLen < fruRecordDataFormatLength)
+ {
+ lg2::error("Invalid fru len: {FRULEN}", "FRULEN", fruLen);
+ return {};
+ }
+
+ std::vector<FruRecordDataFormat> frus;
+
+ size_t index = 0;
+ while (index < fruLen)
+ {
+ FruRecordDataFormat fru;
+
+ auto record = reinterpret_cast<const pldm_fru_record_data_format*>(
+ fruData + index);
+ fru.fruRSI = (int)le16toh(record->record_set_id);
+ fru.fruRecType = record->record_type;
+ fru.fruNum = record->num_fru_fields;
+ fru.fruEncodeType = record->encoding_type;
+
+ index += 5;
+
+ std::ranges::for_each(std::views::iota(0, (int)record->num_fru_fields),
+ [fruData, &fru, &index](int) {
+ auto tlv =
+ reinterpret_cast<const pldm_fru_record_tlv*>(fruData + index);
+ FruTLV frutlv;
+ frutlv.fruFieldType = tlv->type;
+ frutlv.fruFieldLen = tlv->length;
+ frutlv.fruFieldValue.resize(tlv->length);
+ for (const auto& i : std::views::iota(0, (int)tlv->length))
+ {
+ memcpy(frutlv.fruFieldValue.data() + i, tlv->value + i, 1);
+ }
+ fru.fruTLV.push_back(frutlv);
+
+ // 2: 1byte FRU Field Type, 1byte FRU Field Length
+ index += fruFieldTypeLength + (unsigned)tlv->length;
+ });
+
+ frus.push_back(fru);
+ }
+
+ return frus;
+}
} // namespace pdr_utils
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/pdr_utils.hpp b/libpldmresponder/pdr_utils.hpp
index 739058e..b44120a 100644
--- a/libpldmresponder/pdr_utils.hpp
+++ b/libpldmresponder/pdr_utils.hpp
@@ -38,6 +38,22 @@
PLDM_SENSOR_ID
};
+struct FruTLV
+{
+ uint8_t fruFieldType;
+ uint8_t fruFieldLen;
+ std::vector<uint8_t> fruFieldValue;
+};
+
+struct FruRecordDataFormat
+{
+ uint16_t fruRSI;
+ uint8_t fruRecType;
+ uint8_t fruNum;
+ uint8_t fruEncodeType;
+ std::vector<FruTLV> fruTLV;
+};
+
/** @struct PdrEntry
* PDR entry structure that acts as a PDR record structure in the PDR
* repository to handle PDR APIs.
@@ -214,6 +230,18 @@
pldm::pdr::SensorInfo>
parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr);
+/** @brief Parse FRU record table and return the vector of the FRU record data
+ * format structure
+ *
+ * @param[in] fruData - fru data
+ * @param[in] fruLen - fru len
+ *
+ * @return std::vector<FruRecordDataFormat> - the vector of the FRU record data
+ * format structure
+ */
+std::vector<FruRecordDataFormat> parseFruRecordTable(const uint8_t* fruData,
+ size_t fruLen);
+
} // namespace pdr_utils
} // namespace responder
} // namespace pldm