pldmtool: Support parsing Redfish Resource/Action PDRs
Add support for parsing Redfish Resource/Action PDRs to pldmtool.
Tested:
The output of the GetPDR command for SmartNIC card now contains parsed
Redfish Resource/Action PDRs.
Example:
"""
...
{
"nextRecordHandle": 3002,
"responseCount": 89,
"recordHandle": 3001,
"PDRHeaderVersion": 1,
"PDRType": "Redfish Action PDR",
"recordChangeNumber": 0,
"dataLength": 79,
"ActionPDRIndex": 0,
"RelatedResourceCount": 1,
"RelatedResourceID[0]": 1,
"ActionCount": 1,
"ActionNameLengthBytes[0]": 23,
"ActionName[0]": "ResetSettingsToDefault",
"ActionPathLengthBytes[0]": 46,
"ActionPath[0]": "Actions/NetworkAdapter.ResetSettingsToDefault"
}
...
{
"nextRecordHandle": 4003,
"responseCount": 135,
"recordHandle": 4001,
"PDRHeaderVersion": 1,
"PDRType": "Redfish Resource PDR",
"recordChangeNumber": 0,
"dataLength": 125,
"ResourceID": 1,
"ResourceFlags": "Device Root|Contained in collection(3)",
"ContainingResourceID": 0,
"ProposedContainingResourceLengthBytes": 50,
"ProposedContainingResourceName":
"NetworkAdapterCollection.NetworkAdapterCollection",
"SubURILengthBytes": 1,
"SubURI": "",
"AdditionalResourceIDCount": 1,
"AdditionalResourceID[0]": 11,
"AdditionalResourceSubURILengthBytes[0]": 10,
"AdditionalResourceSubURI[0]": "/Settings",
"MajorSchemaVersion": "1.9.0",
"MajorSchemaDictionaryLengthBytes": 1765,
"MajorSchemaDictionarySignature": 50776613,
"MajorSchemaNameLength": 30,
"MajorSchemaName": "NetworkAdapter.NetworkAdapter",
"OEMCount": 0
}
...
"""
Change-Id: I8d6723e8d75833b06067f60395dffa7c8a2e860b
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index 8cd5f83..6b4e945 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -3,6 +3,7 @@
#include "common/utils.hpp"
#include "pldm_cmd_helper.hpp"
+#include <libpldm/base.h>
#include <libpldm/entity.h>
#include <libpldm/platform.h>
#include <libpldm/state_set.h>
@@ -942,6 +943,8 @@
{PLDM_NUMERIC_EFFECTER_INITIALIZATION_PDR,
"Numeric Effecter Initialization PDR"},
{PLDM_COMPACT_NUMERIC_SENSOR_PDR, "Compact Numeric Sensor PDR"},
+ {PLDM_REDFISH_RESOURCE_PDR, "Redfish Resource PDR"},
+ {PLDM_REDFISH_ACTION_PDR, "Redfish Action PDR"},
{PLDM_STATE_EFFECTER_PDR, "State Effecter PDR"},
{PLDM_STATE_EFFECTER_INITIALIZATION_PDR,
"State Effecter Initialization PDR"},
@@ -1160,6 +1163,33 @@
}
}
+ std::string parseRedfishResourcePDRResourceFlags(
+ const bitfield8_t* resourceFlags)
+ {
+ std::string resourceFlagsString;
+ if (resourceFlags->bits.bit0)
+ {
+ resourceFlagsString += "Device Root";
+ }
+ if (resourceFlags->bits.bit1)
+ {
+ if (!resourceFlagsString.empty())
+ {
+ resourceFlagsString += "|";
+ }
+ resourceFlagsString += "Contained in collection";
+ }
+ if (resourceFlags->bits.bit2)
+ {
+ if (!resourceFlagsString.empty())
+ {
+ resourceFlagsString += "|";
+ }
+ resourceFlagsString += "Collection";
+ }
+ return resourceFlagsString;
+ }
+
std::string getPDRType(uint8_t type)
{
auto typeString = std::to_string(type);
@@ -1622,6 +1652,159 @@
return false;
}
+ void printRedfishActionPDR(const uint8_t* data, const uint16_t data_length,
+ ordered_json& output)
+ {
+ struct pldm_platform_redfish_action_pdr pdr;
+ int rc =
+ decode_pldm_platform_redfish_action_pdr(data, data_length, &pdr);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "Failed to decode Redfish Action PDR" << std::endl;
+ return;
+ }
+
+ output["ActionPDRIndex"] = pdr.action_pdr_index;
+ output["RelatedResourceCount"] = pdr.related_resource_count;
+ uint16_t related_resource_count = 0;
+ uint32_t related_resource_id;
+ foreach_pldm_platform_redfish_action_pdr_related_resource_id(
+ pdr, related_resource_id, rc)
+ {
+ output["RelatedResourceID[" +
+ std::to_string(related_resource_count) + "]"] =
+ related_resource_id;
+ related_resource_count++;
+ }
+ if (rc)
+ {
+ std::cerr << "Failed to parse Host Resource Information area"
+ << std::endl;
+ return;
+ }
+
+ output["ActionCount"] = pdr.action_count;
+ uint8_t action_count = 0;
+ struct pldm_platform_redfish_action_pdr_action action;
+ foreach_pldm_platform_redfish_action_pdr_action(pdr, action, rc)
+ {
+ output["ActionNameLengthBytes[" + std::to_string(action_count) +
+ "]"] = action.name.length;
+ output["ActionName[" + std::to_string(action_count) + "]"] =
+ std::string((const char*)(action.name.ptr));
+ output["ActionPathLengthBytes[" + std::to_string(action_count) +
+ "]"] = action.path.length;
+ output["ActionPath[" + std::to_string(action_count) + "]"] =
+ std::string((const char*)(action.path.ptr));
+ action_count++;
+ }
+ if (rc)
+ {
+ std::cerr << "Failed to parse Action Information area" << std::endl;
+ return;
+ }
+ }
+
+ void printRedfishResourcePDR(const uint8_t* data,
+ const uint16_t data_length,
+ ordered_json& output)
+ {
+ struct pldm_platform_redfish_resource_pdr pdr;
+ int rc =
+ decode_pldm_platform_redfish_resource_pdr(data, data_length, &pdr);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "Failed to decode Redfish Resource PDR" << std::endl;
+ return;
+ }
+
+ output["ResourceID"] = pdr.resource_id;
+ std::string resourceFlagsString =
+ parseRedfishResourcePDRResourceFlags(&pdr.resource_flags);
+ if (!resourceFlagsString.empty())
+ {
+ output["ResourceFlags"] =
+ resourceFlagsString + "(" +
+ std::to_string(pdr.resource_flags.byte) + ")";
+ }
+ else
+ {
+ output["ResourceFlags"] = std::to_string(pdr.resource_flags.byte);
+ }
+ output["ContainingResourceID"] = pdr.containing_resource_id;
+ output["ProposedContainingResourceLengthBytes"] =
+ pdr.proposed_containing_resource_name.length;
+ output["ProposedContainingResourceName"] = std::string(
+ (const char*)(pdr.proposed_containing_resource_name.ptr));
+ output["SubURILengthBytes"] = pdr.sub_uri.length;
+ output["SubURI"] = std::string((const char*)(pdr.sub_uri.ptr));
+
+ output["AdditionalResourceIDCount"] = pdr.additional_resource_id_count;
+
+ uint16_t additional_resource_id_count = 0;
+ struct pldm_platform_redfish_resource_pdr_additional_resource
+ additional_resource;
+ foreach_pldm_platform_redfish_resource_pdr_additional_resource(
+ pdr, additional_resource, rc)
+ {
+ output["AdditionalResourceID[" +
+ std::to_string(additional_resource_id_count) + "]"] =
+ additional_resource.id;
+ output["AdditionalResourceSubURILengthBytes[" +
+ std::to_string(additional_resource_id_count) + "]"] =
+ additional_resource.sub_uri.length;
+ output["AdditionalResourceSubURI[" +
+ std::to_string(additional_resource_id_count) + "]"] =
+ std::string((const char*)(additional_resource.sub_uri.ptr));
+ additional_resource_id_count++;
+ }
+ if (rc)
+ {
+ std::cerr << "Failed to parse Additional Resources area"
+ << std::endl;
+ return;
+ }
+
+ char buffer[16] = {0};
+ if ((pdr.major_schema_version.major != 0xff) &&
+ (pdr.major_schema_version.minor != 0xff) &&
+ (pdr.major_schema_version.update != 0xff) &&
+ (pdr.major_schema_version.alpha != 0xff))
+ {
+ pldm_base_ver2str(&(pdr.major_schema_version), buffer,
+ sizeof(buffer));
+ output["MajorSchemaVersion"] = buffer;
+ }
+ else
+ {
+ output["MajorSchemaVersion"] = "Unversioned";
+ }
+ output["MajorSchemaDictionaryLengthBytes"] =
+ pdr.major_schema_dictionary_length_bytes;
+ output["MajorSchemaDictionarySignature"] =
+ pdr.major_schema_dictionary_signature;
+ output["MajorSchemaNameLength"] = pdr.major_schema_name.length;
+ output["MajorSchemaName"] =
+ std::string((const char*)(pdr.major_schema_name.ptr));
+
+ output["OEMCount"] = pdr.oem_count;
+ struct pldm_platform_redfish_resource_pdr_oem_name oem_name;
+ uint16_t oem_count = 0;
+ foreach_pldm_platform_redfish_resource_pdr_oem_name(pdr, oem_name, rc)
+ {
+ output["OEMNameLengthBytes[" + std::to_string(oem_count) + "]"] =
+ oem_name.name.length;
+ output["OEMName[" + std::to_string(oem_count) + "]"] =
+ std::string((const char*)(oem_name.name.ptr));
+ oem_count++;
+ }
+ if (rc)
+ {
+ std::cerr << "Failed to parse OEM Names area" << std::endl;
+ return;
+ }
+ }
+
void printTerminusLocatorPDR(const uint8_t* data, ordered_json& output)
{
const std::array<std::string_view, 4> terminusLocatorType = {
@@ -1979,6 +2162,12 @@
case PLDM_COMPACT_NUMERIC_SENSOR_PDR:
printCompactNumericSensorPDR(data, output);
break;
+ case PLDM_REDFISH_RESOURCE_PDR:
+ printRedfishResourcePDR(data, respCnt, output);
+ break;
+ case PLDM_REDFISH_ACTION_PDR:
+ printRedfishActionPDR(data, respCnt, output);
+ break;
default:
break;
}