pldmtool : File table parsing
This commit implements parsing of the file attribute
table by issuing the GetFileTable command with the
-t option which specifies the pldm file table type.
Tested:
./pldmtool oem-ibm -h
oem type command
Usage: ./pldmtool oem-ibm [OPTIONS] SUBCOMMAND
Options:
-h,--help Print this help message and exit
Subcommands:
GetAlertStatus get alert status descriptor
GetFileTable get file table
./pldmtool oem-ibm GetFileTable
Request Message:
08 01 80 3f 01 00 00 00 00 01 00
Success in creating the socket : RC = 3
Success in connecting to socket : RC = 0
Success in sending message type as pldm to mctp : RC = 0
Write to socket successful : RC = 11
Total length:71
Shutdown Socket successful : RC = 0
Response Message:
08 01 00 3f 01 00 00 00 00 00 05 00 00 00 00 0a 00 50 48 59 50 2d 4e 56 52 41 4d 00 b0 10 01 01 00 00 00 01 00 00 00 10 00 50 48 59 50 2d 4e 56 52 41 4d 2d 43 4b 53 55 4d 10 00 00 00 04 00 00 00 00 00 87 55 62 3e
FileHandle[0]:0
FileNameLength[0]:10
FileName[0]:PHYP-NVRAM
FileSize[0]:17870848
FileTraits[0]:1
FileHandle[1]:1
FileNameLength[1]:16
FileName[1]:PHYP-NVRAM-CKSUM
FileSize[1]:16
FileTraits[1]:4
Change-Id: I44de4dd33fee42df7cdc67eaaddf259ea83346ae
Signed-off-by: Pavithra Barithaya <pbaritha@in.ibm.com>
diff --git a/oem/ibm/libpldm/file_io.h b/oem/ibm/libpldm/file_io.h
index 38e50ca..2aa7bd4 100644
--- a/oem/ibm/libpldm/file_io.h
+++ b/oem/ibm/libpldm/file_io.h
@@ -178,6 +178,16 @@
uint8_t table_data[1]; //!< Table Data
} __attribute__((packed));
+/** @struct pldm_file_attr_table_entry
+ *
+ * Structure representing File attribute table entry
+ */
+struct pldm_file_attr_table_entry {
+ uint32_t file_handle; //!< File Handle
+ uint16_t file_name_length; //!< File name length
+ uint8_t file_attr_table_nst[1]; //!< File name size traits
+} __attribute__((packed));
+
/** @brief Decode GetFileTable command request data
*
* @param[in] msg - Pointer to PLDM request message
diff --git a/pldmtool/meson.build b/pldmtool/meson.build
index 48f4c26..f6eda88 100644
--- a/pldmtool/meson.build
+++ b/pldmtool/meson.build
@@ -11,7 +11,7 @@
if get_option('oem-ibm').enabled()
sources += [
- 'oem/ibm/pldm_host_cmd.cpp'
+ 'oem/ibm/pldm_oem_ibm.cpp',
]
endif
diff --git a/pldmtool/oem/ibm/pldm_host_cmd.cpp b/pldmtool/oem/ibm/pldm_host_cmd.cpp
deleted file mode 100644
index 4f14e8c..0000000
--- a/pldmtool/oem/ibm/pldm_host_cmd.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "pldm_host_cmd.hpp"
-
-#include "oem/ibm/libpldm/host.h"
-
-#include "../../pldm_cmd_helper.hpp"
-
-namespace pldmtool
-{
-
-namespace oem_ibm
-{
-namespace power_host
-{
-using namespace pldmtool::helper;
-
-std::vector<std::unique_ptr<CommandInterface>> commands;
-
-class GetAlertStatus : public CommandInterface
-{
- public:
- ~GetAlertStatus() = default;
- GetAlertStatus() = delete;
- GetAlertStatus(const GetAlertStatus&) = delete;
- GetAlertStatus(GetAlertStatus&&) = default;
- GetAlertStatus& operator=(const GetAlertStatus&) = delete;
- GetAlertStatus& operator=(GetAlertStatus&&) = default;
-
- explicit GetAlertStatus(const char* type, const char* name, CLI::App* app) :
- CommandInterface(type, name, app)
- {
- app->add_option(
- "-i, --id", versionId,
- "Version of the command/response format. 0x00 for this format")
- ->required();
- }
-
- std::pair<int, std::vector<uint8_t>> createRequestMsg() override
- {
- std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
- PLDM_GET_ALERT_STATUS_REQ_BYTES);
- auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
-
- auto rc = encode_get_alert_status_req(instanceId, versionId, request,
- PLDM_GET_ALERT_STATUS_REQ_BYTES);
- return {rc, requestMsg};
- }
-
- void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
- {
- uint8_t completionCode = 0;
- uint32_t rack_entry = 0;
- uint32_t pri_cec_node = 0;
- auto rc = decode_get_alert_status_resp(responsePtr, payloadLength,
- &completionCode, &rack_entry,
- &pri_cec_node);
-
- if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
- {
- std::cerr << "Response Message Error: "
- << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
- return;
- }
-
- std::cout << "GetAlertStatus Success: " << std::endl;
- std::cout << "rack entry: 0x" << std::setfill('0') << std::setw(8)
- << std::hex << (int)rack_entry << std::endl;
- std::cout << "pri cec node: 0x" << std::setfill('0') << std::setw(8)
- << std::hex << (int)pri_cec_node << std::endl;
- }
-
- private:
- uint8_t versionId;
-};
-
-void registerCommand(CLI::App& app)
-{
- auto oem_ibm = app.add_subcommand("oem-ibm", "oem type command");
- oem_ibm->require_subcommand(1);
-
- auto getAlertStatus = oem_ibm->add_subcommand(
- "GetAlertStatus", "get alert status descriptor");
- commands.push_back(std::make_unique<GetAlertStatus>(
- "oem_ibm", "getAlertStatus", getAlertStatus));
-}
-} // namespace power_host
-} // namespace oem_ibm
-} // namespace pldmtool
diff --git a/pldmtool/oem/ibm/pldm_oem_ibm.cpp b/pldmtool/oem/ibm/pldm_oem_ibm.cpp
new file mode 100644
index 0000000..2cea225
--- /dev/null
+++ b/pldmtool/oem/ibm/pldm_oem_ibm.cpp
@@ -0,0 +1,212 @@
+#include "pldm_oem_ibm.hpp"
+
+#include "oem/ibm/libpldm/file_io.h"
+#include "oem/ibm/libpldm/host.h"
+#include "pldm_types.h"
+
+#include "../../pldm_cmd_helper.hpp"
+
+#include <endian.h>
+
+#include <iostream>
+#include <string>
+namespace pldmtool
+{
+
+namespace oem_ibm
+{
+namespace
+{
+
+using namespace pldmtool::helper;
+
+std::vector<std::unique_ptr<CommandInterface>> commands;
+
+const std::map<const char*, pldm_fileio_table_type> pldmFileIOTableTypes{
+ {"AttributeTable", PLDM_FILE_ATTRIBUTE_TABLE},
+};
+
+constexpr uint8_t CHKSUM_PADDING = 8;
+
+} // namespace
+
+class GetAlertStatus : public CommandInterface
+{
+ public:
+ ~GetAlertStatus() = default;
+ GetAlertStatus() = delete;
+ GetAlertStatus(const GetAlertStatus&) = delete;
+ GetAlertStatus(GetAlertStatus&&) = default;
+ GetAlertStatus& operator=(const GetAlertStatus&) = delete;
+ GetAlertStatus& operator=(GetAlertStatus&&) = default;
+
+ explicit GetAlertStatus(const char* type, const char* name, CLI::App* app) :
+ CommandInterface(type, name, app)
+ {
+ app->add_option(
+ "-i, --id", versionId,
+ "Version of the command/response format. 0x00 for this format")
+ ->required();
+ }
+
+ std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+ {
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+ PLDM_GET_ALERT_STATUS_REQ_BYTES);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ auto rc = encode_get_alert_status_req(instanceId, versionId, request,
+ PLDM_GET_ALERT_STATUS_REQ_BYTES);
+ return {rc, requestMsg};
+ }
+
+ void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+ {
+ uint8_t completionCode = 0;
+ uint32_t rack_entry = 0;
+ uint32_t pri_cec_node = 0;
+ auto rc = decode_get_alert_status_resp(responsePtr, payloadLength,
+ &completionCode, &rack_entry,
+ &pri_cec_node);
+
+ if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+ {
+ std::cerr << "Response Message Error: "
+ << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
+ return;
+ }
+
+ std::cout << "GetAlertStatus Success: " << std::endl;
+ std::cout << "rack entry: 0x" << std::setfill('0') << std::setw(8)
+ << std::hex << (int)rack_entry << std::endl;
+ std::cout << "pri cec node: 0x" << std::setfill('0') << std::setw(8)
+ << std::hex << (int)pri_cec_node << std::endl;
+ }
+
+ private:
+ uint8_t versionId;
+};
+
+class GetFileTable : public CommandInterface
+{
+ public:
+ ~GetFileTable() = default;
+ GetFileTable() = delete;
+ GetFileTable(const GetFileTable&) = delete;
+ GetFileTable(GetFileTable&&) = default;
+ GetFileTable& operator=(const GetFileTable&) = delete;
+ GetFileTable& operator=(GetFileTable&&) = default;
+
+ using CommandInterface::CommandInterface;
+
+ std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+ {
+
+ return {PLDM_ERROR, {}};
+ }
+
+ void parseResponseMsg(pldm_msg*, size_t) override
+ {}
+ void exec()
+ {
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+ PLDM_GET_FILE_TABLE_REQ_BYTES);
+
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ auto rc = encode_get_file_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
+ 0, request);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
+ return;
+ }
+
+ std::vector<uint8_t> responseMsg;
+ rc = pldmSendRecv(requestMsg, responseMsg);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
+ return;
+ }
+
+ uint8_t cc = 0;
+ uint8_t transferFlag = 0;
+ uint32_t nextTransferHandle = 0;
+ size_t fileTableDataLength = 0;
+ uint8_t table_data_start_offset;
+ auto responsePtr =
+ reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+ auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
+
+ rc = decode_get_file_table_resp(
+ responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
+ &table_data_start_offset, &fileTableDataLength);
+
+ if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
+ {
+ std::cerr << "Response Message Error: "
+ << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
+ return;
+ }
+
+ auto tableData = reinterpret_cast<uint8_t*>((responsePtr->payload) +
+ table_data_start_offset);
+ printFileAttrTable(tableData, fileTableDataLength);
+ }
+
+ void printFileAttrTable(uint8_t* data, size_t length)
+ {
+ if (data == NULL || length == 0)
+ {
+ return;
+ }
+
+ auto startptr = data;
+ auto endptr = startptr + length - CHKSUM_PADDING;
+
+ while (startptr < endptr)
+ {
+ auto filetableData =
+ reinterpret_cast<pldm_file_attr_table_entry*>(startptr);
+ std::cout << "FileHandle:" << filetableData->file_handle
+ << std::endl;
+ startptr += sizeof(filetableData->file_handle);
+
+ auto nameLength = filetableData->file_name_length;
+ std::cout << " FileNameLength:" << nameLength << std::endl;
+ startptr += sizeof(filetableData->file_name_length);
+
+ std::cout << " FileName:" << startptr << std::endl;
+ startptr += nameLength;
+
+ auto fileSize = *(reinterpret_cast<uint32_t*>(startptr));
+ std::cout << " FileSize:" << le32toh(fileSize) << std::endl;
+ startptr += sizeof(fileSize);
+
+ auto fileTraits =
+ (*(reinterpret_cast<bitfield32_t*>(startptr))).value;
+ std::cout << " FileTraits:" << le32toh(fileTraits) << std::endl;
+ startptr += sizeof(fileTraits);
+ }
+ }
+};
+
+void registerCommand(CLI::App& app)
+{
+ auto oem_ibm = app.add_subcommand("oem-ibm", "oem type command");
+ oem_ibm->require_subcommand(1);
+
+ auto getAlertStatus = oem_ibm->add_subcommand(
+ "GetAlertStatus", "get alert status descriptor");
+ commands.push_back(std::make_unique<GetAlertStatus>(
+ "oem_ibm", "getAlertStatus", getAlertStatus));
+
+ auto getFileTable =
+ oem_ibm->add_subcommand("GetFileTable", "get file table");
+
+ commands.push_back(std::make_unique<GetFileTable>("oem_ibm", "getFileTable",
+ getFileTable));
+}
+} // namespace oem_ibm
+} // namespace pldmtool
diff --git a/pldmtool/oem/ibm/pldm_host_cmd.hpp b/pldmtool/oem/ibm/pldm_oem_ibm.hpp
similarity index 86%
rename from pldmtool/oem/ibm/pldm_host_cmd.hpp
rename to pldmtool/oem/ibm/pldm_oem_ibm.hpp
index d57ccd4..e2af83d 100644
--- a/pldmtool/oem/ibm/pldm_host_cmd.hpp
+++ b/pldmtool/oem/ibm/pldm_oem_ibm.hpp
@@ -7,13 +7,9 @@
namespace oem_ibm
{
-namespace power_host
-{
void registerCommand(CLI::App& app);
-}
-
} // namespace oem_ibm
} // namespace pldmtool
diff --git a/pldmtool/pldmtool.cpp b/pldmtool/pldmtool.cpp
index 4b65b2a..f52c1e8 100644
--- a/pldmtool/pldmtool.cpp
+++ b/pldmtool/pldmtool.cpp
@@ -3,7 +3,7 @@
#include "pldm_cmd_helper.hpp"
#include "pldm_fru_cmd.hpp"
#include "pldm_platform_cmd.hpp"
-#include "pldmtool/oem/ibm/pldm_host_cmd.hpp"
+#include "pldmtool/oem/ibm/pldm_oem_ibm.hpp"
#include <CLI/CLI.hpp>
@@ -74,7 +74,7 @@
pldmtool::fru::registerCommand(app);
#ifdef OEM_IBM
- pldmtool::oem_ibm::power_host::registerCommand(app);
+ pldmtool::oem_ibm::registerCommand(app);
#endif
CLI11_PARSE(app, argc, argv);