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