1 #include "pldm_oem_ibm.hpp"
2
3 #include "../../pldm_cmd_helper.hpp"
4
5 #include <endian.h>
6 #include <libpldm/oem/ibm/file_io.h>
7 #include <libpldm/oem/ibm/host.h>
8 #include <libpldm/pldm_types.h>
9
10 #include <iostream>
11 #include <string>
12 namespace pldmtool
13 {
14
15 namespace oem_ibm
16 {
17 namespace
18 {
19
20 using namespace pldmtool::helper;
21
22 std::vector<std::unique_ptr<CommandInterface>> commands;
23
24 const std::map<const char*, pldm_fileio_table_type> pldmFileIOTableTypes{
25 {"AttributeTable", PLDM_FILE_ATTRIBUTE_TABLE},
26 };
27
28 constexpr uint8_t CHKSUM_PADDING = 8;
29
30 } // namespace
31
32 class GetAlertStatus : public CommandInterface
33 {
34 public:
35 ~GetAlertStatus() = default;
36 GetAlertStatus() = delete;
37 GetAlertStatus(const GetAlertStatus&) = delete;
38 GetAlertStatus(GetAlertStatus&&) = default;
39 GetAlertStatus& operator=(const GetAlertStatus&) = delete;
40 GetAlertStatus& operator=(GetAlertStatus&&) = delete;
41
GetAlertStatus(const char * type,const char * name,CLI::App * app)42 explicit GetAlertStatus(const char* type, const char* name, CLI::App* app) :
43 CommandInterface(type, name, app)
44 {
45 app->add_option(
46 "-i, --id", versionId,
47 "Version of the command/response format. 0x00 for this format")
48 ->required();
49 }
50
createRequestMsg()51 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
52 {
53 std::vector<uint8_t> requestMsg(
54 sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_REQ_BYTES);
55 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
56
57 auto rc = encode_get_alert_status_req(instanceId, versionId, request,
58 PLDM_GET_ALERT_STATUS_REQ_BYTES);
59 return {rc, requestMsg};
60 }
61
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)62 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
63 {
64 uint8_t completionCode = 0;
65 uint32_t rack_entry = 0;
66 uint32_t pri_cec_node = 0;
67 auto rc = decode_get_alert_status_resp(
68 responsePtr, payloadLength, &completionCode, &rack_entry,
69 &pri_cec_node);
70
71 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
72 {
73 std::cerr << "Response Message Error: "
74 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
75 return;
76 }
77
78 std::stringstream re;
79 std::stringstream pcn;
80 ordered_json data;
81 re << "0x" << std::setfill('0') << std::setw(8) << std::hex
82 << (int)rack_entry;
83 pcn << "0x" << std::setfill('0') << std::setw(8) << std::hex
84 << (int)pri_cec_node;
85 data["rack entry"] = re.str();
86 data["pri cec node"] = pcn.str();
87 pldmtool::helper::DisplayInJson(data);
88 }
89
90 private:
91 uint8_t versionId;
92 };
93
94 class GetFileTable : public CommandInterface
95 {
96 public:
97 ~GetFileTable() = default;
98 GetFileTable() = delete;
99 GetFileTable(const GetFileTable&) = delete;
100 GetFileTable(GetFileTable&&) = default;
101 GetFileTable& operator=(const GetFileTable&) = delete;
102 GetFileTable& operator=(GetFileTable&&) = delete;
103
104 using CommandInterface::CommandInterface;
105
createRequestMsg()106 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
107 {
108 return {PLDM_ERROR, {}};
109 }
110
parseResponseMsg(pldm_msg *,size_t)111 void parseResponseMsg(pldm_msg*, size_t) override {}
exec()112 void exec() override
113 {
114 std::vector<uint8_t> requestMsg(
115 sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES);
116
117 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
118
119 auto rc = encode_get_file_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
120 0, request);
121 if (rc != PLDM_SUCCESS)
122 {
123 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
124 return;
125 }
126
127 std::vector<uint8_t> responseMsg;
128 rc = pldmSendRecv(requestMsg, responseMsg);
129 if (rc != PLDM_SUCCESS)
130 {
131 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
132 return;
133 }
134
135 uint8_t cc = 0;
136 uint8_t transferFlag = 0;
137 uint32_t nextTransferHandle = 0;
138 size_t fileTableDataLength = 0;
139 uint8_t table_data_start_offset;
140 auto responsePtr =
141 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
142 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
143
144 rc = decode_get_file_table_resp(
145 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
146 &table_data_start_offset, &fileTableDataLength);
147
148 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
149 {
150 std::cerr << "Response Message Error: "
151 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
152 return;
153 }
154
155 auto tableData = reinterpret_cast<uint8_t*>(
156 (responsePtr->payload) + table_data_start_offset);
157 printFileAttrTable(tableData, fileTableDataLength);
158 }
159
printFileAttrTable(uint8_t * data,size_t length)160 void printFileAttrTable(uint8_t* data, size_t length)
161 {
162 if (data == nullptr || length == 0)
163 {
164 return;
165 }
166
167 auto startptr = data;
168 auto endptr = startptr + length - CHKSUM_PADDING;
169 ordered_json kwVal;
170
171 while (startptr < endptr)
172 {
173 ordered_json fdata;
174 auto filetableData =
175 reinterpret_cast<pldm_file_attr_table_entry*>(startptr);
176 fdata["FileHandle"] = std::to_string(filetableData->file_handle);
177 startptr += sizeof(filetableData->file_handle);
178
179 auto nameLength = filetableData->file_name_length;
180 fdata["FileNameLength"] = nameLength;
181 startptr += sizeof(filetableData->file_name_length);
182
183 fdata["FileName"] = (std::string(
184 reinterpret_cast<const char*>(startptr), nameLength));
185 startptr += nameLength;
186
187 auto fileSize = *(reinterpret_cast<uint32_t*>(startptr));
188 fdata["FileSize"] = le32toh(fileSize);
189 startptr += sizeof(fileSize);
190
191 auto fileTraits =
192 (*(reinterpret_cast<bitfield32_t*>(startptr))).value;
193 fdata["FileTraits"] = le32toh(fileTraits);
194 startptr += sizeof(fileTraits);
195 kwVal.emplace_back(fdata);
196 }
197 pldmtool::helper::DisplayInJson(kwVal);
198 }
199 };
200
registerCommand(CLI::App & app)201 void registerCommand(CLI::App& app)
202 {
203 auto oem_ibm = app.add_subcommand("oem-ibm", "oem type command");
204 oem_ibm->require_subcommand(1);
205
206 auto getAlertStatus = oem_ibm->add_subcommand(
207 "GetAlertStatus", "get alert status descriptor");
208 commands.push_back(std::make_unique<GetAlertStatus>(
209 "oem_ibm", "getAlertStatus", getAlertStatus));
210
211 auto getFileTable =
212 oem_ibm->add_subcommand("GetFileTable", "get file table");
213
214 commands.push_back(std::make_unique<GetFileTable>("oem_ibm", "getFileTable",
215 getFileTable));
216 }
217 } // namespace oem_ibm
218 } // namespace pldmtool
219