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::cout << "GetAlertStatus Success: " << std::endl; 80 std::cout << "rack entry: 0x" << std::setfill('0') << std::setw(8) 81 << std::hex << (int)rack_entry << std::endl; 82 std::cout << "pri cec node: 0x" << std::setfill('0') << std::setw(8) 83 << std::hex << (int)pri_cec_node << std::endl; 84 } 85 86 private: 87 uint8_t versionId; 88 }; 89 90 class GetFileTable : public CommandInterface 91 { 92 public: 93 ~GetFileTable() = default; 94 GetFileTable() = delete; 95 GetFileTable(const GetFileTable&) = delete; 96 GetFileTable(GetFileTable&&) = default; 97 GetFileTable& operator=(const GetFileTable&) = delete; 98 GetFileTable& operator=(GetFileTable&&) = default; 99 100 using CommandInterface::CommandInterface; 101 102 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 103 { 104 105 return {PLDM_ERROR, {}}; 106 } 107 108 void parseResponseMsg(pldm_msg*, size_t) override 109 {} 110 void exec() 111 { 112 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 113 PLDM_GET_FILE_TABLE_REQ_BYTES); 114 115 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 116 117 auto rc = encode_get_file_table_req(instanceId, 0, PLDM_GET_FIRSTPART, 118 0, request); 119 if (rc != PLDM_SUCCESS) 120 { 121 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl; 122 return; 123 } 124 125 std::vector<uint8_t> responseMsg; 126 rc = pldmSendRecv(requestMsg, responseMsg); 127 if (rc != PLDM_SUCCESS) 128 { 129 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl; 130 return; 131 } 132 133 uint8_t cc = 0; 134 uint8_t transferFlag = 0; 135 uint32_t nextTransferHandle = 0; 136 size_t fileTableDataLength = 0; 137 uint8_t table_data_start_offset; 138 auto responsePtr = 139 reinterpret_cast<struct pldm_msg*>(responseMsg.data()); 140 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr); 141 142 rc = decode_get_file_table_resp( 143 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag, 144 &table_data_start_offset, &fileTableDataLength); 145 146 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 147 { 148 std::cerr << "Response Message Error: " 149 << ", rc=" << rc << ", cc=" << (int)cc << std::endl; 150 return; 151 } 152 153 auto tableData = reinterpret_cast<uint8_t*>((responsePtr->payload) + 154 table_data_start_offset); 155 printFileAttrTable(tableData, fileTableDataLength); 156 } 157 158 void printFileAttrTable(uint8_t* data, size_t length) 159 { 160 if (data == NULL || length == 0) 161 { 162 return; 163 } 164 165 auto startptr = data; 166 auto endptr = startptr + length - CHKSUM_PADDING; 167 168 while (startptr < endptr) 169 { 170 auto filetableData = 171 reinterpret_cast<pldm_file_attr_table_entry*>(startptr); 172 std::cout << "FileHandle:" << filetableData->file_handle 173 << std::endl; 174 startptr += sizeof(filetableData->file_handle); 175 176 auto nameLength = filetableData->file_name_length; 177 std::cout << " FileNameLength:" << nameLength << std::endl; 178 startptr += sizeof(filetableData->file_name_length); 179 180 std::cout << " FileName:" << startptr << std::endl; 181 startptr += nameLength; 182 183 auto fileSize = *(reinterpret_cast<uint32_t*>(startptr)); 184 std::cout << " FileSize:" << le32toh(fileSize) << std::endl; 185 startptr += sizeof(fileSize); 186 187 auto fileTraits = 188 (*(reinterpret_cast<bitfield32_t*>(startptr))).value; 189 std::cout << " FileTraits:" << le32toh(fileTraits) << std::endl; 190 startptr += sizeof(fileTraits); 191 } 192 } 193 }; 194 195 void registerCommand(CLI::App& app) 196 { 197 auto oem_ibm = app.add_subcommand("oem-ibm", "oem type command"); 198 oem_ibm->require_subcommand(1); 199 200 auto getAlertStatus = oem_ibm->add_subcommand( 201 "GetAlertStatus", "get alert status descriptor"); 202 commands.push_back(std::make_unique<GetAlertStatus>( 203 "oem_ibm", "getAlertStatus", getAlertStatus)); 204 205 auto getFileTable = 206 oem_ibm->add_subcommand("GetFileTable", "get file table"); 207 208 commands.push_back(std::make_unique<GetFileTable>("oem_ibm", "getFileTable", 209 getFileTable)); 210 } 211 } // namespace oem_ibm 212 } // namespace pldmtool 213