1 #include "pldm_oem_ibm.hpp" 2 3 #include "../../pldm_cmd_helper.hpp" 4 5 #include <endian.h> 6 #include <libpldm/file_io.h> 7 #include <libpldm/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&&) = default; 41 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 51 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 52 { 53 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 54 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 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(responsePtr, payloadLength, 68 &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&&) = default; 103 104 using CommandInterface::CommandInterface; 105 106 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 107 { 108 return {PLDM_ERROR, {}}; 109 } 110 111 void parseResponseMsg(pldm_msg*, size_t) override 112 {} 113 void exec() 114 { 115 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 116 PLDM_GET_FILE_TABLE_REQ_BYTES); 117 118 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 119 120 auto rc = encode_get_file_table_req(instanceId, 0, PLDM_GET_FIRSTPART, 121 0, request); 122 if (rc != PLDM_SUCCESS) 123 { 124 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl; 125 return; 126 } 127 128 std::vector<uint8_t> responseMsg; 129 rc = pldmSendRecv(requestMsg, responseMsg); 130 if (rc != PLDM_SUCCESS) 131 { 132 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl; 133 return; 134 } 135 136 uint8_t cc = 0; 137 uint8_t transferFlag = 0; 138 uint32_t nextTransferHandle = 0; 139 size_t fileTableDataLength = 0; 140 uint8_t table_data_start_offset; 141 auto responsePtr = 142 reinterpret_cast<struct pldm_msg*>(responseMsg.data()); 143 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr); 144 145 rc = decode_get_file_table_resp( 146 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag, 147 &table_data_start_offset, &fileTableDataLength); 148 149 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 150 { 151 std::cerr << "Response Message Error: " 152 << ", rc=" << rc << ", cc=" << (int)cc << std::endl; 153 return; 154 } 155 156 auto tableData = reinterpret_cast<uint8_t*>((responsePtr->payload) + 157 table_data_start_offset); 158 printFileAttrTable(tableData, fileTableDataLength); 159 } 160 161 void printFileAttrTable(uint8_t* data, size_t length) 162 { 163 if (data == NULL || length == 0) 164 { 165 return; 166 } 167 168 auto startptr = data; 169 auto endptr = startptr + length - CHKSUM_PADDING; 170 ordered_json kwVal; 171 172 while (startptr < endptr) 173 { 174 ordered_json fdata; 175 auto filetableData = 176 reinterpret_cast<pldm_file_attr_table_entry*>(startptr); 177 fdata["FileHandle"] = std::to_string(filetableData->file_handle); 178 startptr += sizeof(filetableData->file_handle); 179 180 auto nameLength = filetableData->file_name_length; 181 fdata["FileNameLength"] = nameLength; 182 startptr += sizeof(filetableData->file_name_length); 183 184 fdata["FileName"] = (std::string( 185 reinterpret_cast<char const*>(startptr), nameLength)); 186 startptr += nameLength; 187 188 auto fileSize = *(reinterpret_cast<uint32_t*>(startptr)); 189 fdata["FileSize"] = le32toh(fileSize); 190 startptr += sizeof(fileSize); 191 192 auto fileTraits = 193 (*(reinterpret_cast<bitfield32_t*>(startptr))).value; 194 fdata["FileTraits"] = le32toh(fileTraits); 195 startptr += sizeof(fileTraits); 196 kwVal.emplace_back(fdata); 197 } 198 pldmtool::helper::DisplayInJson(kwVal); 199 } 200 }; 201 202 void registerCommand(CLI::App& app) 203 { 204 auto oem_ibm = app.add_subcommand("oem-ibm", "oem type command"); 205 oem_ibm->require_subcommand(1); 206 207 auto getAlertStatus = oem_ibm->add_subcommand( 208 "GetAlertStatus", "get alert status descriptor"); 209 commands.push_back(std::make_unique<GetAlertStatus>( 210 "oem_ibm", "getAlertStatus", getAlertStatus)); 211 212 auto getFileTable = 213 oem_ibm->add_subcommand("GetFileTable", "get file table"); 214 215 commands.push_back(std::make_unique<GetFileTable>("oem_ibm", "getFileTable", 216 getFileTable)); 217 } 218 } // namespace oem_ibm 219 } // namespace pldmtool 220