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