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 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&&) = delete; 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 void exec() override 113 { 114 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 115 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*>((responsePtr->payload) + 156 table_data_start_offset); 157 printFileAttrTable(tableData, fileTableDataLength); 158 } 159 160 void printFileAttrTable(uint8_t* data, size_t length) 161 { 162 if (data == NULL || 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 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 = oem_ibm->add_subcommand("GetFileTable", 212 "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