Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 1 | #include "pldm_bios_cmd.hpp" |
| 2 | |
| 3 | #include "pldm_cmd_helper.hpp" |
| 4 | |
Sridevi Ramesh | cdfe114 | 2020-01-31 05:42:50 -0600 | [diff] [blame] | 5 | #include "libpldm/bios_table.h" |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 6 | #include "libpldm/utils.h" |
| 7 | |
| 8 | namespace pldmtool |
| 9 | { |
| 10 | |
| 11 | namespace bios |
| 12 | { |
| 13 | |
| 14 | namespace |
| 15 | { |
| 16 | |
| 17 | using namespace pldmtool::helper; |
| 18 | |
| 19 | std::vector<std::unique_ptr<CommandInterface>> commands; |
| 20 | |
Sridevi Ramesh | cdfe114 | 2020-01-31 05:42:50 -0600 | [diff] [blame] | 21 | const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{ |
| 22 | {"StringTable", PLDM_BIOS_STRING_TABLE}, |
| 23 | {"AttributeTable", PLDM_BIOS_ATTR_TABLE}, |
| 24 | {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE}, |
| 25 | }; |
| 26 | |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 27 | } // namespace |
| 28 | |
| 29 | class GetDateTime : public CommandInterface |
| 30 | { |
| 31 | public: |
| 32 | ~GetDateTime() = default; |
| 33 | GetDateTime() = delete; |
| 34 | GetDateTime(const GetDateTime&) = delete; |
| 35 | GetDateTime(GetDateTime&&) = default; |
| 36 | GetDateTime& operator=(const GetDateTime&) = delete; |
| 37 | GetDateTime& operator=(GetDateTime&&) = default; |
| 38 | |
| 39 | using CommandInterface::CommandInterface; |
| 40 | |
| 41 | std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| 42 | { |
| 43 | std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr)); |
| 44 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); |
| 45 | |
| 46 | auto rc = encode_get_date_time_req(PLDM_LOCAL_INSTANCE_ID, request); |
| 47 | return {rc, requestMsg}; |
| 48 | } |
| 49 | |
| 50 | void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override |
| 51 | { |
| 52 | uint8_t cc = 0; |
| 53 | |
| 54 | uint8_t seconds, minutes, hours, day, month; |
| 55 | uint16_t year; |
| 56 | auto rc = |
| 57 | decode_get_date_time_resp(responsePtr, payloadLength, &cc, &seconds, |
| 58 | &minutes, &hours, &day, &month, &year); |
| 59 | if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) |
| 60 | { |
| 61 | std::cerr << "Response Message Error: " |
| 62 | << "rc=" << rc << ",cc=" << (int)cc << std::endl; |
| 63 | return; |
| 64 | } |
| 65 | std::cout << "Date & Time : " << std::endl; |
Sridevi Ramesh | 213a855 | 2020-02-03 00:59:30 -0600 | [diff] [blame] | 66 | std::cout << "YYYY-MM-DD HH:MM:SS - "; |
| 67 | std::cout << bcd2dec16(year); |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 68 | std::cout << "-"; |
| 69 | setWidth(month); |
Sridevi Ramesh | 213a855 | 2020-02-03 00:59:30 -0600 | [diff] [blame] | 70 | std::cout << "-"; |
| 71 | setWidth(day); |
| 72 | std::cout << " "; |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 73 | setWidth(hours); |
| 74 | std::cout << ":"; |
| 75 | setWidth(minutes); |
| 76 | std::cout << ":"; |
| 77 | setWidth(seconds); |
| 78 | std::cout << std::endl; |
| 79 | } |
| 80 | |
| 81 | private: |
| 82 | void setWidth(uint8_t data) |
| 83 | { |
| 84 | std::cout << std::setfill('0') << std::setw(2) |
| 85 | << static_cast<uint32_t>(bcd2dec8(data)); |
| 86 | } |
| 87 | }; |
| 88 | |
George Liu | d664936 | 2019-11-27 19:06:51 +0800 | [diff] [blame] | 89 | class SetDateTime : public CommandInterface |
| 90 | { |
| 91 | public: |
| 92 | ~SetDateTime() = default; |
| 93 | SetDateTime() = delete; |
| 94 | SetDateTime(const SetDateTime&) = delete; |
| 95 | SetDateTime(SetDateTime&&) = default; |
| 96 | SetDateTime& operator=(const SetDateTime&) = delete; |
| 97 | SetDateTime& operator=(SetDateTime&&) = default; |
| 98 | |
| 99 | explicit SetDateTime(const char* type, const char* name, CLI::App* app) : |
| 100 | CommandInterface(type, name, app) |
| 101 | { |
| 102 | app->add_option("-d,--data", tmData, |
| 103 | "set date time data\n" |
| 104 | "eg: YYYYMMDDHHMMSS") |
| 105 | ->required(); |
| 106 | } |
| 107 | |
| 108 | std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| 109 | { |
| 110 | std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + |
| 111 | sizeof(struct pldm_set_date_time_req)); |
| 112 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); |
| 113 | uint16_t year = 0; |
| 114 | uint8_t month = 0; |
| 115 | uint8_t day = 0; |
| 116 | uint8_t hours = 0; |
| 117 | uint8_t minutes = 0; |
| 118 | uint8_t seconds = 0; |
| 119 | |
| 120 | if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes, |
| 121 | &seconds)) |
| 122 | { |
| 123 | std::cerr << "decode date Error: " |
| 124 | << "tmData=" << tmData << std::endl; |
| 125 | |
| 126 | return {PLDM_ERROR_INVALID_DATA, requestMsg}; |
| 127 | } |
| 128 | |
| 129 | auto rc = encode_set_date_time_req( |
| 130 | PLDM_LOCAL_INSTANCE_ID, seconds, minutes, hours, day, month, year, |
| 131 | request, sizeof(struct pldm_set_date_time_req)); |
| 132 | |
| 133 | return {rc, requestMsg}; |
| 134 | } |
| 135 | |
| 136 | void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override |
| 137 | { |
| 138 | uint8_t completionCode = 0; |
| 139 | auto rc = decode_set_date_time_resp(responsePtr, payloadLength, |
| 140 | &completionCode); |
| 141 | |
| 142 | if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) |
| 143 | { |
| 144 | std::cerr << "Response Message Error: " |
| 145 | << "rc=" << rc << ",cc=" << (int)completionCode |
| 146 | << std::endl; |
| 147 | return; |
| 148 | } |
| 149 | |
| 150 | std::cout << "SetDateTime: SUCCESS" << std::endl; |
| 151 | } |
| 152 | |
| 153 | private: |
| 154 | uint64_t tmData; |
| 155 | }; |
| 156 | |
Sridevi Ramesh | cdfe114 | 2020-01-31 05:42:50 -0600 | [diff] [blame] | 157 | class GetBIOSTable : public CommandInterface |
| 158 | { |
| 159 | public: |
| 160 | ~GetBIOSTable() = default; |
| 161 | GetBIOSTable() = delete; |
| 162 | GetBIOSTable(const GetBIOSTable&) = delete; |
| 163 | GetBIOSTable(GetBIOSTable&&) = default; |
| 164 | GetBIOSTable& operator=(const GetBIOSTable&) = delete; |
| 165 | GetBIOSTable& operator=(GetBIOSTable&&) = default; |
| 166 | |
| 167 | using CommandInterface::CommandInterface; |
| 168 | |
| 169 | explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) : |
| 170 | CommandInterface(type, name, app) |
| 171 | { |
| 172 | app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type") |
| 173 | ->required() |
| 174 | ->transform( |
| 175 | CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case)); |
| 176 | } |
| 177 | |
| 178 | std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| 179 | { |
| 180 | uint32_t nextTransferHandle = 32; |
| 181 | |
| 182 | std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + |
| 183 | PLDM_GET_BIOS_TABLE_REQ_BYTES); |
| 184 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); |
| 185 | |
| 186 | auto rc = encode_get_bios_table_req( |
| 187 | PLDM_LOCAL_INSTANCE_ID, nextTransferHandle, PLDM_GET_FIRSTPART, |
| 188 | pldmBIOSTableType, request); |
| 189 | return {rc, requestMsg}; |
| 190 | } |
| 191 | |
| 192 | void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override |
| 193 | { |
| 194 | uint8_t cc = 0, transferFlag = 0; |
| 195 | uint32_t nextTransferHandle = 0; |
| 196 | size_t bios_table_offset; |
| 197 | |
| 198 | auto rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc, |
| 199 | &nextTransferHandle, &transferFlag, |
| 200 | &bios_table_offset); |
| 201 | |
| 202 | if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) |
| 203 | { |
| 204 | std::cerr << "Response Message Error: " |
| 205 | << "rc=" << rc << ",cc=" << (int)cc << std::endl; |
| 206 | return; |
| 207 | } |
| 208 | auto tableData = |
| 209 | reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset); |
| 210 | auto tableSize = |
| 211 | payloadLength - sizeof(nextTransferHandle) - sizeof(transferFlag); |
| 212 | printBIOSTable(tableData, tableSize, pldmBIOSTableType); |
| 213 | } |
| 214 | |
| 215 | private: |
| 216 | pldm_bios_table_types pldmBIOSTableType; |
| 217 | |
| 218 | void decodeStringTable(const void* tableData, size_t tableSize) |
| 219 | { |
| 220 | std::cout << "Parsed Response Msg: " << std::endl; |
| 221 | std::cout << "BIOSStringHandle : BIOSString" << std::endl; |
| 222 | std::string strTableData; |
| 223 | std::unique_ptr<pldm_bios_table_iter, |
| 224 | decltype(&pldm_bios_table_iter_free)> |
| 225 | iter(pldm_bios_table_iter_create(tableData, tableSize, |
| 226 | PLDM_BIOS_STRING_TABLE), |
| 227 | pldm_bios_table_iter_free); |
| 228 | while (!pldm_bios_table_iter_is_end(iter.get())) |
| 229 | { |
| 230 | try |
| 231 | { |
| 232 | auto tableEntry = |
| 233 | pldm_bios_table_iter_string_entry_value(iter.get()); |
| 234 | auto strLength = |
| 235 | pldm_bios_table_string_entry_decode_string_length( |
| 236 | tableEntry); |
| 237 | strTableData.resize(strLength + 1); |
| 238 | auto strHandle = |
| 239 | pldm_bios_table_string_entry_decode_handle(tableEntry); |
| 240 | pldm_bios_table_string_entry_decode_string( |
| 241 | tableEntry, strTableData.data(), strTableData.size()); |
| 242 | std::cout << strHandle << " : " << strTableData << std::endl; |
| 243 | } |
| 244 | catch (const std::exception& e) |
| 245 | { |
| 246 | std::cerr |
| 247 | << "handler fails when traversing BIOSStringTable, ERROR=" |
| 248 | << e.what() << "\n"; |
| 249 | } |
| 250 | pldm_bios_table_iter_next(iter.get()); |
| 251 | } |
| 252 | } |
| 253 | void printBIOSTable(const void* tableData, size_t tableSize, |
| 254 | enum pldm_bios_table_types type) |
| 255 | { |
| 256 | if (!tableSize) |
| 257 | { |
| 258 | std::cerr << "Found table size null." << std::endl; |
| 259 | return; |
| 260 | } |
| 261 | switch (type) |
| 262 | { |
| 263 | case PLDM_BIOS_STRING_TABLE: |
| 264 | decodeStringTable(tableData, tableSize); |
| 265 | break; |
| 266 | default: |
| 267 | break; |
| 268 | } |
| 269 | } |
| 270 | }; |
| 271 | |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 272 | void registerCommand(CLI::App& app) |
| 273 | { |
| 274 | auto bios = app.add_subcommand("bios", "bios type command"); |
| 275 | bios->require_subcommand(1); |
| 276 | auto getDateTime = bios->add_subcommand("GetDateTime", "get date time"); |
| 277 | commands.push_back( |
| 278 | std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime)); |
George Liu | d664936 | 2019-11-27 19:06:51 +0800 | [diff] [blame] | 279 | |
| 280 | auto setDateTime = |
| 281 | bios->add_subcommand("SetDateTime", "set host date time"); |
| 282 | commands.push_back( |
| 283 | std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime)); |
Sridevi Ramesh | cdfe114 | 2020-01-31 05:42:50 -0600 | [diff] [blame] | 284 | |
| 285 | auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table"); |
| 286 | commands.push_back( |
| 287 | std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable)); |
Sridevi Ramesh | 9857643 | 2019-11-27 10:10:28 -0600 | [diff] [blame] | 288 | } |
| 289 | |
| 290 | } // namespace bios |
| 291 | |
| 292 | } // namespace pldmtool |