blob: 3f0d4ec7b86b7b6725d2b134b19dc7879e53a1e4 [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "bios.hpp"
2
George Liu83409572019-12-24 18:42:54 +08003#include "utils.hpp"
Sampa Misra032bd502019-03-06 05:03:22 -06004#include "xyz/openbmc_project/Common/error.hpp"
5
Xiaochao Ma60227a02019-12-04 09:00:12 +08006#include <time.h>
7
Sampa Misra032bd502019-03-06 05:03:22 -06008#include <array>
Sampa Misrab37be312019-07-03 02:26:41 -05009#include <boost/crc.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -060010#include <chrono>
11#include <ctime>
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060012#include <filesystem>
Sampa Misraaa8ae722019-12-12 03:20:40 -060013#include <iostream>
John Wang02700402019-10-06 16:34:29 +080014#include <memory>
Sampa Misrab37be312019-07-03 02:26:41 -050015#include <numeric>
Sampa Misra032bd502019-03-06 05:03:22 -060016#include <stdexcept>
17#include <string>
18#include <variant>
19#include <vector>
20
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060021namespace fs = std::filesystem;
Sampa Misrab37be312019-07-03 02:26:41 -050022using namespace pldm::responder::bios;
23using namespace bios_parser;
Sampa Misrab37be312019-07-03 02:26:41 -050024
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060025constexpr auto stringTableFile = "stringTable";
26constexpr auto attrTableFile = "attributeTable";
27constexpr auto attrValTableFile = "attributeValueTable";
28
Sampa Misra032bd502019-03-06 05:03:22 -060029namespace pldm
30{
31
Sampa Misrab37be312019-07-03 02:26:41 -050032using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Sampa Misra032bd502019-03-06 05:03:22 -060033using EpochTimeUS = uint64_t;
Sampa Misrab37be312019-07-03 02:26:41 -050034using BIOSTableRow = std::vector<uint8_t>;
Carol Wangdc220c82019-08-26 13:31:31 +080035using BIOSJsonName = std::string;
Sampa Misra032bd502019-03-06 05:03:22 -060036
37constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
Sampa Misrab37be312019-07-03 02:26:41 -050038constexpr auto padChksumMax = 7;
Sampa Misra032bd502019-03-06 05:03:22 -060039
40namespace responder
41{
42
43namespace utils
44{
45
46void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
47 uint8_t& hours, uint8_t& day, uint8_t& month,
48 uint16_t& year)
49{
50 auto t = time_t(timeSec);
51 auto time = localtime(&t);
52
George Liu83409572019-12-24 18:42:54 +080053 seconds = pldm::utils::decimalToBcd(time->tm_sec);
54 minutes = pldm::utils::decimalToBcd(time->tm_min);
55 hours = pldm::utils::decimalToBcd(time->tm_hour);
56 day = pldm::utils::decimalToBcd(time->tm_mday);
57 month = pldm::utils::decimalToBcd(time->tm_mon +
58 1); // The number of months in the range
59 // 0 to 11.PLDM expects range 1 to 12
60 year = pldm::utils::decimalToBcd(time->tm_year +
61 1900); // The number of years since 1900
Sampa Misra032bd502019-03-06 05:03:22 -060062}
63
Xiaochao Ma60227a02019-12-04 09:00:12 +080064std::time_t timeToEpoch(uint8_t seconds, uint8_t minutes, uint8_t hours,
65 uint8_t day, uint8_t month, uint16_t year)
66{
67 struct std::tm stm;
68
69 stm.tm_year = year - 1900;
70 stm.tm_mon = month - 1;
71 stm.tm_mday = day;
72 stm.tm_hour = hours;
73 stm.tm_min = minutes;
74 stm.tm_sec = seconds;
75 stm.tm_isdst = -1;
76
77 // It will get the time in seconds since
78 // Epoch, 1970.1.1 00:00:00 +0000,UTC.
79 return timegm(&stm);
80}
81
John Wangc2938352019-09-30 13:58:41 +080082size_t getTableTotalsize(size_t sizeWithoutPad)
83{
John Wang79c37f12019-10-31 15:46:31 +080084 return sizeWithoutPad + pldm_bios_table_pad_checksum_size(sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080085}
86
87void padAndChecksum(Table& table)
88{
John Wang79c37f12019-10-31 15:46:31 +080089 auto sizeWithoutPad = table.size();
90 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
91 table.resize(table.size() + padAndChecksumSize);
John Wangc2938352019-09-30 13:58:41 +080092
John Wang79c37f12019-10-31 15:46:31 +080093 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
94 sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080095}
96
Sampa Misra032bd502019-03-06 05:03:22 -060097} // namespace utils
98
Deepak Kodihallibc669f12019-11-28 08:52:07 -060099namespace bios
100{
101
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600102Handler::Handler()
103{
104 try
105 {
106 fs::remove(
107 fs::path(std::string(BIOS_TABLES_DIR) + "/" + stringTableFile));
108 fs::remove(
109 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrTableFile));
110 fs::remove(
111 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrValTableFile));
112 }
113 catch (const std::exception& e)
114 {
115 }
Xiaochao Ma60227a02019-12-04 09:00:12 +0800116 handlers.emplace(PLDM_SET_DATE_TIME,
117 [this](const pldm_msg* request, size_t payloadLength) {
118 return this->setDateTime(request, payloadLength);
119 });
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600120 handlers.emplace(PLDM_GET_DATE_TIME,
121 [this](const pldm_msg* request, size_t payloadLength) {
122 return this->getDateTime(request, payloadLength);
123 });
124 handlers.emplace(PLDM_GET_BIOS_TABLE,
125 [this](const pldm_msg* request, size_t payloadLength) {
126 return this->getBIOSTable(request, payloadLength);
127 });
John Wang8721ed62019-12-05 14:44:43 +0800128 handlers.emplace(PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
129 [this](const pldm_msg* request, size_t payloadLength) {
130 return this->getBIOSAttributeCurrentValueByHandle(
131 request, payloadLength);
132 });
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600133}
134
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600135Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
Sampa Misra032bd502019-03-06 05:03:22 -0600136{
137 uint8_t seconds = 0;
138 uint8_t minutes = 0;
139 uint8_t hours = 0;
140 uint8_t day = 0;
141 uint8_t month = 0;
142 uint16_t year = 0;
143
144 constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
George Liu408c3c42019-10-16 16:49:15 +0800145 constexpr auto hostTimePath = "/xyz/openbmc_project/time/host";
vkaverapa6575b82019-04-03 05:33:52 -0500146 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
147 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liu782d37f2020-01-24 09:02:17 +0800148 EpochTimeUS timeUsec;
Sampa Misra032bd502019-03-06 05:03:22 -0600149
Sampa Misra032bd502019-03-06 05:03:22 -0600150 try
151 {
George Liu782d37f2020-01-24 09:02:17 +0800152 timeUsec = pldm::utils::DBusHandler().getDbusProperty<EpochTimeUS>(
153 hostTimePath, "Elapsed", timeInterface);
Sampa Misra032bd502019-03-06 05:03:22 -0600154 }
George Liu0e02c322020-01-01 09:41:51 +0800155 catch (const sdbusplus::exception::SdBusError& e)
Sampa Misra032bd502019-03-06 05:03:22 -0600156 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600157 std::cerr << "Error getting time, PATH=" << hostTimePath
158 << " TIME INTERACE=" << timeInterface << "\n";
Sampa Misra032bd502019-03-06 05:03:22 -0600159
George Liufb8611d2019-12-06 10:14:15 +0800160 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Sampa Misra032bd502019-03-06 05:03:22 -0600161 }
162
Sampa Misra032bd502019-03-06 05:03:22 -0600163 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
164 std::chrono::microseconds(timeUsec))
165 .count();
166
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600167 pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
168 day, month, year);
Sampa Misra032bd502019-03-06 05:03:22 -0600169
George Liufb8611d2019-12-06 10:14:15 +0800170 auto rc = encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS,
171 seconds, minutes, hours, day, month,
172 year, responsePtr);
173 if (rc != PLDM_SUCCESS)
174 {
175 return ccOnlyResponse(request, rc);
176 }
177
vkaverapa6575b82019-04-03 05:33:52 -0500178 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600179}
180
Xiaochao Ma60227a02019-12-04 09:00:12 +0800181Response Handler::setDateTime(const pldm_msg* request, size_t payloadLength)
182{
183 uint8_t seconds = 0;
184 uint8_t minutes = 0;
185 uint8_t hours = 0;
186 uint8_t day = 0;
187 uint8_t month = 0;
188 uint16_t year = 0;
189 std::time_t timeSec;
190
191 constexpr auto setTimeInterface = "xyz.openbmc_project.Time.EpochTime";
192 constexpr auto setTimePath = "/xyz/openbmc_project/time/host";
193 constexpr auto timeSetPro = "Elapsed";
194
195 auto rc = decode_set_date_time_req(request, payloadLength, &seconds,
196 &minutes, &hours, &day, &month, &year);
197 if (rc != PLDM_SUCCESS)
198 {
199 return ccOnlyResponse(request, rc);
200 }
201 timeSec = pldm::responder::utils::timeToEpoch(seconds, minutes, hours, day,
202 month, year);
203 uint64_t timeUsec = std::chrono::duration_cast<std::chrono::microseconds>(
204 std::chrono::seconds(timeSec))
205 .count();
206 std::variant<uint64_t> value{timeUsec};
207 try
208 {
209 pldm::utils::DBusHandler().setDbusProperty(setTimePath, timeSetPro,
210 setTimeInterface, value);
211 }
212 catch (std::exception& e)
213 {
214
215 std::cerr << "Error Setting time,PATH=" << setTimePath
216 << "TIME INTERFACE=" << setTimeInterface
217 << "ERROR=" << e.what() << "\n";
218
219 return ccOnlyResponse(request, PLDM_ERROR);
220 }
221
222 return ccOnlyResponse(request, PLDM_SUCCESS);
223}
224
Sampa Misrab37be312019-07-03 02:26:41 -0500225/** @brief Construct the BIOS string table
226 *
George Liufb8611d2019-12-06 10:14:15 +0800227 * @param[in,out] BIOSStringTable - the string table
228 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500229 */
George Liufb8611d2019-12-06 10:14:15 +0800230Response getBIOSStringTable(BIOSTable& BIOSStringTable, const pldm_msg* request)
John Wange96e7e52019-10-05 17:47:30 +0800231
Sampa Misrab37be312019-07-03 02:26:41 -0500232{
233 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
234 0);
235 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
John Wangdd9a6282019-10-11 18:52:46 +0800236 if (!BIOSStringTable.isEmpty())
237 {
George Liufb8611d2019-12-06 10:14:15 +0800238 auto rc = encode_get_bios_table_resp(
239 request->hdr.instance_id, PLDM_SUCCESS,
240 0, /* next transfer handle */
241 PLDM_START_AND_END, nullptr, response.size(),
242 responsePtr); // filling up the header here
243 if (rc != PLDM_SUCCESS)
244 {
245 return CmdHandler::ccOnlyResponse(request, rc);
246 }
247
Sampa Misrab37be312019-07-03 02:26:41 -0500248 BIOSStringTable.load(response);
John Wangdd9a6282019-10-11 18:52:46 +0800249 return response;
250 }
251 auto biosStrings = bios_parser::getStrings();
252 std::sort(biosStrings.begin(), biosStrings.end());
253 // remove all duplicate strings received from bios json
254 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
255 biosStrings.end());
256
257 size_t sizeWithoutPad = std::accumulate(
258 biosStrings.begin(), biosStrings.end(), 0,
259 [](size_t sum, const std::string& elem) {
260 return sum +
261 pldm_bios_table_string_entry_encode_length(elem.length());
262 });
263
264 Table stringTable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600265 stringTable.reserve(
266 pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
John Wangdd9a6282019-10-11 18:52:46 +0800267
268 stringTable.resize(sizeWithoutPad);
269 auto tablePtr = stringTable.data();
270 for (const auto& elem : biosStrings)
271 {
272 auto entry_length =
273 pldm_bios_table_string_entry_encode_length(elem.length());
274 pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
275 elem.c_str(), elem.length());
276 tablePtr += entry_length;
277 sizeWithoutPad -= entry_length;
Sampa Misrab37be312019-07-03 02:26:41 -0500278 }
279
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600280 pldm::responder::utils::padAndChecksum(stringTable);
John Wangdd9a6282019-10-11 18:52:46 +0800281 BIOSStringTable.store(stringTable);
282 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
283 stringTable.size(),
284 0);
285 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800286 auto rc = encode_get_bios_table_resp(
287 request->hdr.instance_id, PLDM_SUCCESS, 0 /* nxtTransferHandle */,
288 PLDM_START_AND_END, stringTable.data(), response.size(), responsePtr);
289 if (rc != PLDM_SUCCESS)
290 {
291 return CmdHandler::ccOnlyResponse(request, rc);
292 }
293
Sampa Misrab37be312019-07-03 02:26:41 -0500294 return response;
295}
296
297/** @brief Find the string handle from the BIOS string table given the name
298 *
299 * @param[in] name - name of the BIOS string
300 * @param[in] BIOSStringTable - the string table
301 * @return - uint16_t - handle of the string
302 */
303StringHandle findStringHandle(const std::string& name,
304 const BIOSTable& BIOSStringTable)
305{
John Wangdd9a6282019-10-11 18:52:46 +0800306 Table table;
307 BIOSStringTable.load(table);
308 auto stringEntry = pldm_bios_table_string_find_by_string(
309 table.data(), table.size(), name.c_str());
310 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500311 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600312 std::cerr << "Reached end of BIOS string table,did not find the "
313 << "handle for the string, STRING=" << name.c_str() << "\n";
314 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500315 }
John Wangdd9a6282019-10-11 18:52:46 +0800316
317 return pldm_bios_table_string_entry_decode_handle(stringEntry);
Sampa Misrab37be312019-07-03 02:26:41 -0500318}
319
320/** @brief Find the string name from the BIOS string table for a string handle
321 *
322 * @param[in] stringHdl - string handle
323 * @param[in] BIOSStringTable - the string table
324 *
325 * @return - std::string - name of the corresponding BIOS string
326 */
327std::string findStringName(StringHandle stringHdl,
328 const BIOSTable& BIOSStringTable)
329{
John Wangdd9a6282019-10-11 18:52:46 +0800330 Table table;
331 BIOSStringTable.load(table);
332 auto stringEntry = pldm_bios_table_string_find_by_handle(
333 table.data(), table.size(), stringHdl);
Sampa Misrab37be312019-07-03 02:26:41 -0500334 std::string name;
John Wangdd9a6282019-10-11 18:52:46 +0800335 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500336 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600337 std::cerr << "Reached end of BIOS string table,did not find "
338 << "string name for handle, STRING_HANDLE=" << stringHdl
339 << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500340 }
John Wangdd9a6282019-10-11 18:52:46 +0800341 auto strLength =
342 pldm_bios_table_string_entry_decode_string_length(stringEntry);
343 name.resize(strLength);
344 pldm_bios_table_string_entry_decode_string(stringEntry, name.data(),
345 name.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500346 return name;
347}
348
349namespace bios_type_enum
350{
351
Carol Wangdc220c82019-08-26 13:31:31 +0800352using namespace bios_parser::bios_enum;
353
Sampa Misrab37be312019-07-03 02:26:41 -0500354/** @brief Find the indices into the array of the possible values of string
355 * handles for the current values.This is used in attribute value table
356 *
357 * @param[in] possiVals - vector of string handles comprising all the possible
358 * values for an attribute
359 * @param[in] currVals - vector of strings comprising all current values
360 * for an attribute
361 * @param[in] BIOSStringTable - the string table
362 *
363 * @return - std::vector<uint8_t> - indices into the array of the possible
364 * values of string handles
365 */
366std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
367 CurrentValues currVals,
368 const BIOSTable& BIOSStringTable)
369{
370 std::vector<uint8_t> stringIndices;
371
372 for (const auto& currVal : currVals)
373 {
374 StringHandle curHdl;
375 try
376 {
377 curHdl = findStringHandle(currVal, BIOSStringTable);
378 }
379 catch (InternalFailure& e)
380 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600381 std::cerr << "Exception fetching handle for the string, STRING="
382 << currVal.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500383 continue;
384 }
385
386 uint8_t i = 0;
387 for (auto possiHdl : possiVals)
388 {
389 if (possiHdl == curHdl)
390 {
391 stringIndices.push_back(i);
392 break;
393 }
394 i++;
395 }
396 }
397 return stringIndices;
398}
399
400/** @brief Find the indices into the array of the possible values of string
401 * handles for the default values. This is used in attribute table
402 *
403 * @param[in] possiVals - vector of strings comprising all the possible values
404 * for an attribute
405 * @param[in] defVals - vector of strings comprising all the default values
406 * for an attribute
407 * @return - std::vector<uint8_t> - indices into the array of the possible
408 * values of string
409 */
410std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
411 const DefaultValues& defVals)
412{
413 std::vector<uint8_t> defHdls;
414 for (const auto& defs : defVals)
415 {
416 auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
417 if (index != possiVals.end())
418 {
419 defHdls.push_back(index - possiVals.begin());
420 }
421 }
422
423 return defHdls;
424}
425
426/** @brief Construct the attibute table for BIOS type Enumeration and
427 * Enumeration ReadOnly
428 * @param[in] BIOSStringTable - the string table
429 * @param[in] biosJsonDir - path where the BIOS json files are present
Carol Wangdc220c82019-08-26 13:31:31 +0800430 * @param[in,out] attributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500431 *
Sampa Misrab37be312019-07-03 02:26:41 -0500432 */
John Wange96e7e52019-10-05 17:47:30 +0800433void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500434{
Sampa Misrab37be312019-07-03 02:26:41 -0500435 const auto& attributeMap = getValues();
Sampa Misrab37be312019-07-03 02:26:41 -0500436 StringHandle strHandle;
437
438 for (const auto& [key, value] : attributeMap)
439 {
440 try
441 {
442 strHandle = findStringHandle(key, BIOSStringTable);
443 }
444 catch (InternalFailure& e)
445 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600446 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
447 << key.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500448 continue;
449 }
John Wangccc04552019-10-14 14:28:25 +0800450 bool readOnly = (std::get<0>(value));
Sampa Misrab37be312019-07-03 02:26:41 -0500451 PossibleValues possiVals = std::get<1>(value);
452 DefaultValues defVals = std::get<2>(value);
453 // both the possible and default values are stored in sorted manner to
454 // ease in fetching back/comparison
455 std::sort(possiVals.begin(), possiVals.end());
456 std::sort(defVals.begin(), defVals.end());
457
458 std::vector<StringHandle> possiValsByHdl;
459 for (const auto& elem : possiVals)
460 {
461 try
462 {
463 auto hdl = findStringHandle(elem, BIOSStringTable);
464 possiValsByHdl.push_back(std::move(hdl));
465 }
466 catch (InternalFailure& e)
467 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600468 std::cerr << "Could not find handle for BIOS string, STRING="
469 << elem.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500470 continue;
471 }
472 }
473 auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
John Wangccc04552019-10-14 14:28:25 +0800474 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
475 possiValsByHdl.size(), defValsByHdl.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500476
John Wangccc04552019-10-14 14:28:25 +0800477 auto attrTableSize = attributeTable.size();
478 attributeTable.resize(attrTableSize + entryLength, 0);
479 struct pldm_bios_table_attr_entry_enum_info info = {
480 strHandle,
481 readOnly,
482 (uint8_t)possiValsByHdl.size(),
483 possiValsByHdl.data(),
484 (uint8_t)defValsByHdl.size(),
485 defValsByHdl.data(),
486 };
487 pldm_bios_table_attr_entry_enum_encode(
488 attributeTable.data() + attrTableSize, entryLength, &info);
Sampa Misrab37be312019-07-03 02:26:41 -0500489 }
Sampa Misrab37be312019-07-03 02:26:41 -0500490}
491
John Wang3ad21752019-10-06 16:42:21 +0800492void constructAttrValueEntry(
493 const struct pldm_bios_attr_table_entry* attrTableEntry,
494 const std::string& attrName, const BIOSTable& BIOSStringTable,
495 Table& attrValueTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500496{
John Wang3ad21752019-10-06 16:42:21 +0800497 CurrentValues currVals;
498 try
Sampa Misrab37be312019-07-03 02:26:41 -0500499 {
John Wang3ad21752019-10-06 16:42:21 +0800500 currVals = getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500501 }
John Wang3ad21752019-10-06 16:42:21 +0800502 catch (const std::exception& e)
503 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600504 std::cerr << "getAttrValue returned error for attribute, NAME="
505 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800506 return;
507 }
508 uint8_t pv_num =
509 pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
510 PossibleValuesByHandle pvHdls(pv_num, 0);
511 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
512 pvHdls.data(), pv_num);
513 std::sort(currVals.begin(), currVals.end());
514
515 auto currValStrIndices = findStrIndices(pvHdls, currVals, BIOSStringTable);
516
517 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
518 currValStrIndices.size());
519 auto tableSize = attrValueTable.size();
520 attrValueTable.resize(tableSize + entryLength);
521 pldm_bios_table_attr_value_entry_encode_enum(
522 attrValueTable.data() + tableSize, entryLength,
523 attrTableEntry->attr_handle, attrTableEntry->attr_type,
524 currValStrIndices.size(), currValStrIndices.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500525}
526
527} // end namespace bios_type_enum
528
Carol Wangdc220c82019-08-26 13:31:31 +0800529namespace bios_type_string
530{
Carol Wang612f35b2019-08-26 17:14:26 +0800531
532using namespace bios_parser::bios_string;
533
Carol Wangdc220c82019-08-26 13:31:31 +0800534/** @brief Construct the attibute table for BIOS type String and
535 * String ReadOnly
536 * @param[in] BIOSStringTable - the string table
537 * @param[in] biosJsonDir - path where the BIOS json files are present
538 * @param[in,out] attributeTable - the attribute table
539 *
540 */
John Wange96e7e52019-10-05 17:47:30 +0800541void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Carol Wangdc220c82019-08-26 13:31:31 +0800542{
Carol Wang612f35b2019-08-26 17:14:26 +0800543 const auto& attributeMap = getValues();
544 StringHandle strHandle;
Carol Wang612f35b2019-08-26 17:14:26 +0800545 for (const auto& [key, value] : attributeMap)
546 {
547 try
548 {
549 strHandle = findStringHandle(key, BIOSStringTable);
550 }
551 catch (InternalFailure& e)
552 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600553 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
554 << key.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +0800555 continue;
556 }
557
John Wangccc04552019-10-14 14:28:25 +0800558 const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
Carol Wang612f35b2019-08-26 17:14:26 +0800559 defaultStr] = value;
John Wangccc04552019-10-14 14:28:25 +0800560 auto entryLength =
561 pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
Carol Wang612f35b2019-08-26 17:14:26 +0800562
John Wangccc04552019-10-14 14:28:25 +0800563 struct pldm_bios_table_attr_entry_string_info info = {
564 strHandle, readOnly, strType, minStrLen,
565 maxStrLen, defaultStrLen, defaultStr.data(),
566 };
567 auto attrTableSize = attributeTable.size();
568 attributeTable.resize(attrTableSize + entryLength, 0);
569 pldm_bios_table_attr_entry_string_encode(
570 attributeTable.data() + attrTableSize, entryLength, &info);
Carol Wang612f35b2019-08-26 17:14:26 +0800571 }
Carol Wangdc220c82019-08-26 13:31:31 +0800572}
Carol Wangb503f9e2019-09-02 16:34:10 +0800573
John Wang3ad21752019-10-06 16:42:21 +0800574void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
575 const std::string& attrName,
Carol Wangb503f9e2019-09-02 16:34:10 +0800576 const BIOSTable& BIOSStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800577 Table& attrValueTable)
Carol Wangb503f9e2019-09-02 16:34:10 +0800578{
John Wang3ad21752019-10-06 16:42:21 +0800579 std::ignore = BIOSStringTable;
580 std::string currStr;
581 uint16_t currStrLen = 0;
582 try
Carol Wangb503f9e2019-09-02 16:34:10 +0800583 {
John Wang3ad21752019-10-06 16:42:21 +0800584 currStr = getAttrValue(attrName);
585 currStrLen = currStr.size();
Carol Wangb503f9e2019-09-02 16:34:10 +0800586 }
John Wang3ad21752019-10-06 16:42:21 +0800587 catch (const std::exception& e)
588 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600589 std::cerr << "getAttrValue returned error for attribute, NAME="
590 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800591 return;
592 }
593 auto entryLength =
594 pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
595 auto tableSize = attrValueTable.size();
596 attrValueTable.resize(tableSize + entryLength);
597 pldm_bios_table_attr_value_entry_encode_string(
598 attrValueTable.data() + tableSize, entryLength,
599 attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
600 currStr.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800601}
602
Carol Wangdc220c82019-08-26 13:31:31 +0800603} // end namespace bios_type_string
604
John Wangdbbc9ff2019-10-25 13:53:46 +0800605namespace bios_type_integer
606{
607
608using namespace bios_parser::bios_integer;
609
610/** @brief Construct the attibute table for BIOS type Integer and
611 * Integer ReadOnly
612 * @param[in] BIOSStringTable - the string table
613 * @param[in,out] attributeTable - the attribute table
614 *
615 */
616void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
617{
618 const auto& attributeMap = getValues();
619 StringHandle strHandle;
620 for (const auto& [key, value] : attributeMap)
621 {
622 try
623 {
624 strHandle = findStringHandle(key, BIOSStringTable);
625 }
626 catch (InternalFailure& e)
627 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600628 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
629 << key.c_str() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800630 continue;
631 }
632
633 const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
634 defaultValue] = value;
635 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
636
637 struct pldm_bios_table_attr_entry_integer_info info = {
638 strHandle, readOnly, lowerBound,
639 upperBound, scalarIncrement, defaultValue,
640 };
641 auto attrTableSize = attributeTable.size();
642 attributeTable.resize(attrTableSize + entryLength, 0);
643 pldm_bios_table_attr_entry_integer_encode(
644 attributeTable.data() + attrTableSize, entryLength, &info);
645 }
646}
647
648void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
649 const std::string& attrName,
650 const BIOSTable& BIOSStringTable,
651 Table& attrValueTable)
652{
653 std::ignore = BIOSStringTable;
654 uint64_t currentValue;
655 try
656 {
657 currentValue = getAttrValue(attrName);
658 }
659 catch (const std::exception& e)
660 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600661 std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
662 << " ERROR=" << e.what() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800663 return;
664 }
665 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
666 auto tableSize = attrValueTable.size();
667 attrValueTable.resize(tableSize + entryLength);
668 pldm_bios_table_attr_value_entry_encode_integer(
669 attrValueTable.data() + tableSize, entryLength,
670 attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
671}
672
673} // namespace bios_type_integer
674
John Wang02700402019-10-06 16:34:29 +0800675void traverseBIOSAttrTable(const Table& biosAttrTable,
676 AttrTableEntryHandler handler)
677{
678 std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
679 iter(pldm_bios_table_iter_create(biosAttrTable.data(),
680 biosAttrTable.size(),
681 PLDM_BIOS_ATTR_TABLE),
682 pldm_bios_table_iter_free);
683 while (!pldm_bios_table_iter_is_end(iter.get()))
684 {
685 auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
686 try
687 {
688 handler(table_entry);
689 }
690 catch (const std::exception& e)
691 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600692 std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
693 << e.what() << "\n";
John Wang02700402019-10-06 16:34:29 +0800694 }
695 pldm_bios_table_iter_next(iter.get());
696 }
697}
698
John Wange96e7e52019-10-05 17:47:30 +0800699using typeHandler = std::function<void(const BIOSTable& BIOSStringTable,
700 Table& attributeTable)>;
Carol Wangdc220c82019-08-26 13:31:31 +0800701std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
702 {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
John Wangdbbc9ff2019-10-25 13:53:46 +0800703 {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
704 {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
705};
Carol Wangdc220c82019-08-26 13:31:31 +0800706
Sampa Misrab37be312019-07-03 02:26:41 -0500707/** @brief Construct the BIOS attribute table
708 *
George Liufb8611d2019-12-06 10:14:15 +0800709 * @param[in,out] BIOSAttributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500710 * @param[in] BIOSStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500711 * @param[in] biosJsonDir - path where the BIOS json files are present
George Liufb8611d2019-12-06 10:14:15 +0800712 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500713 */
714Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
715 const BIOSTable& BIOSStringTable,
George Liufb8611d2019-12-06 10:14:15 +0800716 const char* biosJsonDir, const pldm_msg* request)
Sampa Misrab37be312019-07-03 02:26:41 -0500717{
718 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
719 0);
720 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
721 uint32_t nxtTransferHandle = 0;
722 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500723
724 if (BIOSAttributeTable.isEmpty())
725 { // no persisted table, constructing fresh table and response
Carol Wangdc220c82019-08-26 13:31:31 +0800726 Table attributeTable;
727 fs::path dir(biosJsonDir);
728
729 for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
730 it++)
731 {
732 fs::path file = dir / it->first;
733 if (fs::exists(file))
734 {
John Wange96e7e52019-10-05 17:47:30 +0800735 it->second(BIOSStringTable, attributeTable);
Carol Wangdc220c82019-08-26 13:31:31 +0800736 }
737 }
738
739 if (attributeTable.empty())
740 { // no available json file is found
George Liufb8611d2019-12-06 10:14:15 +0800741 return CmdHandler::ccOnlyResponse(request,
742 PLDM_BIOS_TABLE_UNAVAILABLE);
Carol Wangdc220c82019-08-26 13:31:31 +0800743 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600744 pldm::responder::utils::padAndChecksum(attributeTable);
John Wangc2938352019-09-30 13:58:41 +0800745 BIOSAttributeTable.store(attributeTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500746 response.resize(sizeof(pldm_msg_hdr) +
747 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
748 attributeTable.size());
749 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800750
751 auto rc = encode_get_bios_table_resp(
752 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
753 transferFlag, attributeTable.data(), response.size(), responsePtr);
754 if (rc != PLDM_SUCCESS)
755 {
756 return CmdHandler::ccOnlyResponse(request, rc);
757 }
Sampa Misrab37be312019-07-03 02:26:41 -0500758 }
759 else
760 { // persisted table present, constructing response
George Liufb8611d2019-12-06 10:14:15 +0800761 auto rc = encode_get_bios_table_resp(
762 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
763 transferFlag, nullptr, response.size(),
764 responsePtr); // filling up the header here
765 if (rc != PLDM_SUCCESS)
766 {
767 return CmdHandler::ccOnlyResponse(request, rc);
768 }
Sampa Misrab37be312019-07-03 02:26:41 -0500769 BIOSAttributeTable.load(response);
770 }
771
772 return response;
773}
774
John Wang3ad21752019-10-06 16:42:21 +0800775using AttrValTableEntryConstructHandler =
776 std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
777 const std::string& attrName,
778 const BIOSTable& BIOSStringTable, Table& table)>;
779
780using AttrType = uint8_t;
781const std::map<AttrType, AttrValTableEntryConstructHandler>
782 AttrValTableConstructMap{
783 {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
784 {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
785 {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
786 {PLDM_BIOS_ENUMERATION_READ_ONLY,
787 bios_type_enum::constructAttrValueEntry},
John Wangdbbc9ff2019-10-25 13:53:46 +0800788 {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
789 {PLDM_BIOS_INTEGER_READ_ONLY,
790 bios_type_integer::constructAttrValueEntry},
John Wang3ad21752019-10-06 16:42:21 +0800791 };
792
793void constructAttrValueTableEntry(
794 const struct pldm_bios_attr_table_entry* attrEntry,
795 const BIOSTable& BIOSStringTable, Table& attributeValueTable)
796{
797 auto attrName = findStringName(attrEntry->string_handle, BIOSStringTable);
798 if (attrName.empty())
799 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600800 std::cerr << "invalid string handle, STRING_HANDLE="
801 << attrEntry->string_handle << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800802 return;
803 }
804
805 AttrValTableConstructMap.at(attrEntry->attr_type)(
806 attrEntry, attrName, BIOSStringTable, attributeValueTable);
807}
808
Sampa Misrab37be312019-07-03 02:26:41 -0500809/** @brief Construct the BIOS attribute value table
810 *
George Liufb8611d2019-12-06 10:14:15 +0800811 * @param[in,out] BIOSAttributeValueTable - the attribute value table
Sampa Misrab37be312019-07-03 02:26:41 -0500812 * @param[in] BIOSAttributeTable - the attribute table
813 * @param[in] BIOSStringTable - the string table
George Liufb8611d2019-12-06 10:14:15 +0800814 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500815 */
816Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
817 const BIOSTable& BIOSAttributeTable,
818 const BIOSTable& BIOSStringTable,
George Liufb8611d2019-12-06 10:14:15 +0800819 const pldm_msg* request)
Sampa Misrab37be312019-07-03 02:26:41 -0500820{
821 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
822 0);
823 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
824 uint32_t nxtTransferHandle = 0;
825 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500826
John Wang3ad21752019-10-06 16:42:21 +0800827 if (!BIOSAttributeValueTable.isEmpty())
828 {
George Liufb8611d2019-12-06 10:14:15 +0800829 auto rc = encode_get_bios_table_resp(
830 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
831 transferFlag, nullptr, response.size(),
832 responsePtr); // filling up the header here
833 if (rc != PLDM_SUCCESS)
834 {
835 return CmdHandler::ccOnlyResponse(request, rc);
836 }
837
Sampa Misrab37be312019-07-03 02:26:41 -0500838 BIOSAttributeValueTable.load(response);
John Wang3ad21752019-10-06 16:42:21 +0800839 return response;
Sampa Misrab37be312019-07-03 02:26:41 -0500840 }
841
John Wang3ad21752019-10-06 16:42:21 +0800842 Table attributeValueTable;
843 Table attributeTable;
844 BIOSAttributeTable.load(attributeTable);
845 traverseBIOSAttrTable(
846 attributeTable,
847 [&BIOSStringTable, &attributeValueTable](
848 const struct pldm_bios_attr_table_entry* tableEntry) {
849 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
850 attributeValueTable);
851 });
852 if (attributeValueTable.empty())
853 {
George Liufb8611d2019-12-06 10:14:15 +0800854 return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
John Wang3ad21752019-10-06 16:42:21 +0800855 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600856 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800857 BIOSAttributeValueTable.store(attributeValueTable);
858
859 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
860 attributeValueTable.size());
861 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800862 auto rc = encode_get_bios_table_resp(
863 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle, transferFlag,
864 attributeValueTable.data(), response.size(), responsePtr);
865 if (rc != PLDM_SUCCESS)
866 {
867 return CmdHandler::ccOnlyResponse(request, rc);
868 }
John Wang3ad21752019-10-06 16:42:21 +0800869
Sampa Misrab37be312019-07-03 02:26:41 -0500870 return response;
871}
872
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600873Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
Sampa Misrab37be312019-07-03 02:26:41 -0500874{
Deepak Kodihallic3d20892019-08-01 05:38:31 -0500875 fs::create_directory(BIOS_TABLES_DIR);
Sampa Misrab37be312019-07-03 02:26:41 -0500876 auto response = internal::buildBIOSTables(request, payloadLength,
877 BIOS_JSONS_DIR, BIOS_TABLES_DIR);
878
879 return response;
880}
881
John Wang8721ed62019-12-05 14:44:43 +0800882Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
883 size_t payloadLength)
884{
885 uint32_t transferHandle;
886 uint8_t transferOpFlag;
887 uint16_t attributeHandle;
888
889 auto rc = decode_get_bios_attribute_current_value_by_handle_req(
890 request, payloadLength, &transferHandle, &transferOpFlag,
891 &attributeHandle);
892 if (rc != PLDM_SUCCESS)
893 {
894 return ccOnlyResponse(request, rc);
895 }
896
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600897 fs::path tablesPath(BIOS_TABLES_DIR);
898 auto stringTablePath = tablesPath / stringTableFile;
899 BIOSTable BIOSStringTable(stringTablePath.c_str());
900 auto attrTablePath = tablesPath / attrTableFile;
901 BIOSTable BIOSAttributeTable(attrTablePath.c_str());
902 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
903 {
904 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
905 }
906
907 auto attrValueTablePath = tablesPath / attrValTableFile;
908 BIOSTable BIOSAttributeValueTable(attrValueTablePath.c_str());
909
910 if (BIOSAttributeValueTable.isEmpty())
911 {
912 Table attributeValueTable;
913 Table attributeTable;
914 BIOSAttributeTable.load(attributeTable);
915 traverseBIOSAttrTable(
916 attributeTable,
917 [&BIOSStringTable, &attributeValueTable](
918 const struct pldm_bios_attr_table_entry* tableEntry) {
919 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
920 attributeValueTable);
921 });
922 if (attributeValueTable.empty())
923 {
924 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
925 }
926 pldm::responder::utils::padAndChecksum(attributeValueTable);
927 BIOSAttributeValueTable.store(attributeValueTable);
928 }
John Wang8721ed62019-12-05 14:44:43 +0800929
930 Response table;
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600931 BIOSAttributeValueTable.load(table);
John Wang8721ed62019-12-05 14:44:43 +0800932
933 auto entry = pldm_bios_table_attr_value_find_by_handle(
934 table.data(), table.size(), attributeHandle);
935 if (entry == nullptr)
936 {
937 return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
938 }
939
John Wang8e877e02020-02-03 16:06:55 +0800940 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
John Wang8721ed62019-12-05 14:44:43 +0800941 Response response(sizeof(pldm_msg_hdr) +
942 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
John Wang8e877e02020-02-03 16:06:55 +0800943 entryLength,
John Wang8721ed62019-12-05 14:44:43 +0800944 0);
945 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800946 rc = encode_get_bios_current_value_by_handle_resp(
John Wang8e877e02020-02-03 16:06:55 +0800947 request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END,
948 reinterpret_cast<const uint8_t*>(entry), entryLength, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800949 if (rc != PLDM_SUCCESS)
950 {
951 return ccOnlyResponse(request, rc);
952 }
John Wang8721ed62019-12-05 14:44:43 +0800953
954 return response;
955}
956
Sampa Misrab37be312019-07-03 02:26:41 -0500957namespace internal
958{
959
960Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
961 const char* biosJsonDir, const char* biosTablePath)
962{
963 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
964 0);
Sampa Misrab37be312019-07-03 02:26:41 -0500965
John Wange96e7e52019-10-05 17:47:30 +0800966 if (setupConfig(biosJsonDir) != 0)
967 {
George Liufb8611d2019-12-06 10:14:15 +0800968 return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
John Wange96e7e52019-10-05 17:47:30 +0800969 }
970
Sampa Misrab37be312019-07-03 02:26:41 -0500971 uint32_t transferHandle{};
972 uint8_t transferOpFlag{};
973 uint8_t tableType{};
974
975 auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
976 &transferOpFlag, &tableType);
George Liufb8611d2019-12-06 10:14:15 +0800977 if (rc != PLDM_SUCCESS)
Sampa Misrab37be312019-07-03 02:26:41 -0500978 {
George Liufb8611d2019-12-06 10:14:15 +0800979 return CmdHandler::ccOnlyResponse(request, rc);
980 }
Sampa Misrab37be312019-07-03 02:26:41 -0500981
George Liufb8611d2019-12-06 10:14:15 +0800982 BIOSTable BIOSStringTable(
983 (std::string(biosTablePath) + "/" + stringTableFile).c_str());
984 BIOSTable BIOSAttributeTable(
985 (std::string(biosTablePath) + "/" + attrTableFile).c_str());
986 BIOSTable BIOSAttributeValueTable(
987 (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
988 switch (tableType)
989 {
990 case PLDM_BIOS_STRING_TABLE:
Sampa Misrab37be312019-07-03 02:26:41 -0500991
George Liufb8611d2019-12-06 10:14:15 +0800992 response = getBIOSStringTable(BIOSStringTable, request);
993 break;
994 case PLDM_BIOS_ATTR_TABLE:
995
996 if (BIOSStringTable.isEmpty())
997 {
998 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
999 }
1000 else
1001 {
1002 response = getBIOSAttributeTable(
1003 BIOSAttributeTable, BIOSStringTable, biosJsonDir, request);
1004 }
1005 break;
1006 case PLDM_BIOS_ATTR_VAL_TABLE:
1007 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
1008 {
1009 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
1010 }
1011 else
1012 {
1013 response = getBIOSAttributeValueTable(BIOSAttributeValueTable,
1014 BIOSAttributeTable,
1015 BIOSStringTable, request);
1016 }
1017 break;
1018 default:
1019 rc = PLDM_INVALID_BIOS_TABLE_TYPE;
1020 break;
Sampa Misrab37be312019-07-03 02:26:41 -05001021 }
1022
1023 if (rc != PLDM_SUCCESS)
1024 {
George Liufb8611d2019-12-06 10:14:15 +08001025 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misrab37be312019-07-03 02:26:41 -05001026 }
1027
1028 return response;
1029}
1030
1031} // end namespace internal
1032} // namespace bios
1033
Sampa Misra032bd502019-03-06 05:03:22 -06001034} // namespace responder
1035} // namespace pldm