blob: 13b36ab04c8899f986f515a4685cdb45599d3ca5 [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());
Sampa Misra032bd502019-03-06 05:03:22 -0600148 std::variant<EpochTimeUS> value;
149
Sampa Misra032bd502019-03-06 05:03:22 -0600150 try
151 {
George Liu0e02c322020-01-01 09:41:51 +0800152 value = pldm::utils::DBusHandler()
153 .getDbusProperty<std::variant<EpochTimeUS>>(
154 hostTimePath, "Elapsed", timeInterface);
Sampa Misra032bd502019-03-06 05:03:22 -0600155 }
George Liu0e02c322020-01-01 09:41:51 +0800156 catch (const sdbusplus::exception::SdBusError& e)
Sampa Misra032bd502019-03-06 05:03:22 -0600157 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600158 std::cerr << "Error getting time, PATH=" << hostTimePath
159 << " TIME INTERACE=" << timeInterface << "\n";
Sampa Misra032bd502019-03-06 05:03:22 -0600160
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530161 encode_get_date_time_resp(request->hdr.instance_id, PLDM_ERROR, seconds,
162 minutes, hours, day, month, year,
163 responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500164 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600165 }
166
167 uint64_t timeUsec = std::get<EpochTimeUS>(value);
168
169 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
170 std::chrono::microseconds(timeUsec))
171 .count();
172
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600173 pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
174 day, month, year);
Sampa Misra032bd502019-03-06 05:03:22 -0600175
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530176 encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS, seconds,
177 minutes, hours, day, month, year, responsePtr);
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 *
227 * @param[in] BIOSStringTable - the string table
228 * @param[in] transferHandle - transfer handle to identify part of transfer
229 * @param[in] transferOpFlag - flag to indicate which part of data being
230 * transferred
231 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500232 */
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500233Response getBIOSStringTable(BIOSTable& BIOSStringTable,
234 uint32_t /*transferHandle*/,
John Wange96e7e52019-10-05 17:47:30 +0800235 uint8_t /*transferOpFlag*/, uint8_t instanceID)
236
Sampa Misrab37be312019-07-03 02:26:41 -0500237{
238 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
239 0);
240 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
John Wangdd9a6282019-10-11 18:52:46 +0800241 if (!BIOSStringTable.isEmpty())
242 {
243 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS,
244 0, /* next transfer handle */
245 PLDM_START_AND_END, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500246 responsePtr); // filling up the header here
247 BIOSStringTable.load(response);
John Wangdd9a6282019-10-11 18:52:46 +0800248 return response;
249 }
250 auto biosStrings = bios_parser::getStrings();
251 std::sort(biosStrings.begin(), biosStrings.end());
252 // remove all duplicate strings received from bios json
253 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
254 biosStrings.end());
255
256 size_t sizeWithoutPad = std::accumulate(
257 biosStrings.begin(), biosStrings.end(), 0,
258 [](size_t sum, const std::string& elem) {
259 return sum +
260 pldm_bios_table_string_entry_encode_length(elem.length());
261 });
262
263 Table stringTable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600264 stringTable.reserve(
265 pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
John Wangdd9a6282019-10-11 18:52:46 +0800266
267 stringTable.resize(sizeWithoutPad);
268 auto tablePtr = stringTable.data();
269 for (const auto& elem : biosStrings)
270 {
271 auto entry_length =
272 pldm_bios_table_string_entry_encode_length(elem.length());
273 pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
274 elem.c_str(), elem.length());
275 tablePtr += entry_length;
276 sizeWithoutPad -= entry_length;
Sampa Misrab37be312019-07-03 02:26:41 -0500277 }
278
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600279 pldm::responder::utils::padAndChecksum(stringTable);
John Wangdd9a6282019-10-11 18:52:46 +0800280 BIOSStringTable.store(stringTable);
281 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
282 stringTable.size(),
283 0);
284 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
285 encode_get_bios_table_resp(
286 instanceID, PLDM_SUCCESS, 0 /* nxtTransferHandle */, PLDM_START_AND_END,
287 stringTable.data(), response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500288 return response;
289}
290
291/** @brief Find the string handle from the BIOS string table given the name
292 *
293 * @param[in] name - name of the BIOS string
294 * @param[in] BIOSStringTable - the string table
295 * @return - uint16_t - handle of the string
296 */
297StringHandle findStringHandle(const std::string& name,
298 const BIOSTable& BIOSStringTable)
299{
John Wangdd9a6282019-10-11 18:52:46 +0800300 Table table;
301 BIOSStringTable.load(table);
302 auto stringEntry = pldm_bios_table_string_find_by_string(
303 table.data(), table.size(), name.c_str());
304 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500305 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600306 std::cerr << "Reached end of BIOS string table,did not find the "
307 << "handle for the string, STRING=" << name.c_str() << "\n";
308 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500309 }
John Wangdd9a6282019-10-11 18:52:46 +0800310
311 return pldm_bios_table_string_entry_decode_handle(stringEntry);
Sampa Misrab37be312019-07-03 02:26:41 -0500312}
313
314/** @brief Find the string name from the BIOS string table for a string handle
315 *
316 * @param[in] stringHdl - string handle
317 * @param[in] BIOSStringTable - the string table
318 *
319 * @return - std::string - name of the corresponding BIOS string
320 */
321std::string findStringName(StringHandle stringHdl,
322 const BIOSTable& BIOSStringTable)
323{
John Wangdd9a6282019-10-11 18:52:46 +0800324 Table table;
325 BIOSStringTable.load(table);
326 auto stringEntry = pldm_bios_table_string_find_by_handle(
327 table.data(), table.size(), stringHdl);
Sampa Misrab37be312019-07-03 02:26:41 -0500328 std::string name;
John Wangdd9a6282019-10-11 18:52:46 +0800329 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500330 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600331 std::cerr << "Reached end of BIOS string table,did not find "
332 << "string name for handle, STRING_HANDLE=" << stringHdl
333 << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500334 }
John Wangdd9a6282019-10-11 18:52:46 +0800335 auto strLength =
336 pldm_bios_table_string_entry_decode_string_length(stringEntry);
337 name.resize(strLength);
338 pldm_bios_table_string_entry_decode_string(stringEntry, name.data(),
339 name.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500340 return name;
341}
342
343namespace bios_type_enum
344{
345
Carol Wangdc220c82019-08-26 13:31:31 +0800346using namespace bios_parser::bios_enum;
347
Sampa Misrab37be312019-07-03 02:26:41 -0500348/** @brief Find the indices into the array of the possible values of string
349 * handles for the current values.This is used in attribute value table
350 *
351 * @param[in] possiVals - vector of string handles comprising all the possible
352 * values for an attribute
353 * @param[in] currVals - vector of strings comprising all current values
354 * for an attribute
355 * @param[in] BIOSStringTable - the string table
356 *
357 * @return - std::vector<uint8_t> - indices into the array of the possible
358 * values of string handles
359 */
360std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
361 CurrentValues currVals,
362 const BIOSTable& BIOSStringTable)
363{
364 std::vector<uint8_t> stringIndices;
365
366 for (const auto& currVal : currVals)
367 {
368 StringHandle curHdl;
369 try
370 {
371 curHdl = findStringHandle(currVal, BIOSStringTable);
372 }
373 catch (InternalFailure& e)
374 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600375 std::cerr << "Exception fetching handle for the string, STRING="
376 << currVal.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500377 continue;
378 }
379
380 uint8_t i = 0;
381 for (auto possiHdl : possiVals)
382 {
383 if (possiHdl == curHdl)
384 {
385 stringIndices.push_back(i);
386 break;
387 }
388 i++;
389 }
390 }
391 return stringIndices;
392}
393
394/** @brief Find the indices into the array of the possible values of string
395 * handles for the default values. This is used in attribute table
396 *
397 * @param[in] possiVals - vector of strings comprising all the possible values
398 * for an attribute
399 * @param[in] defVals - vector of strings comprising all the default values
400 * for an attribute
401 * @return - std::vector<uint8_t> - indices into the array of the possible
402 * values of string
403 */
404std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
405 const DefaultValues& defVals)
406{
407 std::vector<uint8_t> defHdls;
408 for (const auto& defs : defVals)
409 {
410 auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
411 if (index != possiVals.end())
412 {
413 defHdls.push_back(index - possiVals.begin());
414 }
415 }
416
417 return defHdls;
418}
419
420/** @brief Construct the attibute table for BIOS type Enumeration and
421 * Enumeration ReadOnly
422 * @param[in] BIOSStringTable - the string table
423 * @param[in] biosJsonDir - path where the BIOS json files are present
Carol Wangdc220c82019-08-26 13:31:31 +0800424 * @param[in,out] attributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500425 *
Sampa Misrab37be312019-07-03 02:26:41 -0500426 */
John Wange96e7e52019-10-05 17:47:30 +0800427void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500428{
Sampa Misrab37be312019-07-03 02:26:41 -0500429 const auto& attributeMap = getValues();
Sampa Misrab37be312019-07-03 02:26:41 -0500430 StringHandle strHandle;
431
432 for (const auto& [key, value] : attributeMap)
433 {
434 try
435 {
436 strHandle = findStringHandle(key, BIOSStringTable);
437 }
438 catch (InternalFailure& e)
439 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600440 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
441 << key.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500442 continue;
443 }
John Wangccc04552019-10-14 14:28:25 +0800444 bool readOnly = (std::get<0>(value));
Sampa Misrab37be312019-07-03 02:26:41 -0500445 PossibleValues possiVals = std::get<1>(value);
446 DefaultValues defVals = std::get<2>(value);
447 // both the possible and default values are stored in sorted manner to
448 // ease in fetching back/comparison
449 std::sort(possiVals.begin(), possiVals.end());
450 std::sort(defVals.begin(), defVals.end());
451
452 std::vector<StringHandle> possiValsByHdl;
453 for (const auto& elem : possiVals)
454 {
455 try
456 {
457 auto hdl = findStringHandle(elem, BIOSStringTable);
458 possiValsByHdl.push_back(std::move(hdl));
459 }
460 catch (InternalFailure& e)
461 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600462 std::cerr << "Could not find handle for BIOS string, STRING="
463 << elem.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500464 continue;
465 }
466 }
467 auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
John Wangccc04552019-10-14 14:28:25 +0800468 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
469 possiValsByHdl.size(), defValsByHdl.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500470
John Wangccc04552019-10-14 14:28:25 +0800471 auto attrTableSize = attributeTable.size();
472 attributeTable.resize(attrTableSize + entryLength, 0);
473 struct pldm_bios_table_attr_entry_enum_info info = {
474 strHandle,
475 readOnly,
476 (uint8_t)possiValsByHdl.size(),
477 possiValsByHdl.data(),
478 (uint8_t)defValsByHdl.size(),
479 defValsByHdl.data(),
480 };
481 pldm_bios_table_attr_entry_enum_encode(
482 attributeTable.data() + attrTableSize, entryLength, &info);
Sampa Misrab37be312019-07-03 02:26:41 -0500483 }
Sampa Misrab37be312019-07-03 02:26:41 -0500484}
485
John Wang3ad21752019-10-06 16:42:21 +0800486void constructAttrValueEntry(
487 const struct pldm_bios_attr_table_entry* attrTableEntry,
488 const std::string& attrName, const BIOSTable& BIOSStringTable,
489 Table& attrValueTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500490{
John Wang3ad21752019-10-06 16:42:21 +0800491 CurrentValues currVals;
492 try
Sampa Misrab37be312019-07-03 02:26:41 -0500493 {
John Wang3ad21752019-10-06 16:42:21 +0800494 currVals = getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500495 }
John Wang3ad21752019-10-06 16:42:21 +0800496 catch (const std::exception& e)
497 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600498 std::cerr << "getAttrValue returned error for attribute, NAME="
499 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800500 return;
501 }
502 uint8_t pv_num =
503 pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
504 PossibleValuesByHandle pvHdls(pv_num, 0);
505 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
506 pvHdls.data(), pv_num);
507 std::sort(currVals.begin(), currVals.end());
508
509 auto currValStrIndices = findStrIndices(pvHdls, currVals, BIOSStringTable);
510
511 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
512 currValStrIndices.size());
513 auto tableSize = attrValueTable.size();
514 attrValueTable.resize(tableSize + entryLength);
515 pldm_bios_table_attr_value_entry_encode_enum(
516 attrValueTable.data() + tableSize, entryLength,
517 attrTableEntry->attr_handle, attrTableEntry->attr_type,
518 currValStrIndices.size(), currValStrIndices.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500519}
520
521} // end namespace bios_type_enum
522
Carol Wangdc220c82019-08-26 13:31:31 +0800523namespace bios_type_string
524{
Carol Wang612f35b2019-08-26 17:14:26 +0800525
526using namespace bios_parser::bios_string;
527
Carol Wangdc220c82019-08-26 13:31:31 +0800528/** @brief Construct the attibute table for BIOS type String and
529 * String ReadOnly
530 * @param[in] BIOSStringTable - the string table
531 * @param[in] biosJsonDir - path where the BIOS json files are present
532 * @param[in,out] attributeTable - the attribute table
533 *
534 */
John Wange96e7e52019-10-05 17:47:30 +0800535void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Carol Wangdc220c82019-08-26 13:31:31 +0800536{
Carol Wang612f35b2019-08-26 17:14:26 +0800537 const auto& attributeMap = getValues();
538 StringHandle strHandle;
Carol Wang612f35b2019-08-26 17:14:26 +0800539 for (const auto& [key, value] : attributeMap)
540 {
541 try
542 {
543 strHandle = findStringHandle(key, BIOSStringTable);
544 }
545 catch (InternalFailure& e)
546 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600547 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
548 << key.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +0800549 continue;
550 }
551
John Wangccc04552019-10-14 14:28:25 +0800552 const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
Carol Wang612f35b2019-08-26 17:14:26 +0800553 defaultStr] = value;
John Wangccc04552019-10-14 14:28:25 +0800554 auto entryLength =
555 pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
Carol Wang612f35b2019-08-26 17:14:26 +0800556
John Wangccc04552019-10-14 14:28:25 +0800557 struct pldm_bios_table_attr_entry_string_info info = {
558 strHandle, readOnly, strType, minStrLen,
559 maxStrLen, defaultStrLen, defaultStr.data(),
560 };
561 auto attrTableSize = attributeTable.size();
562 attributeTable.resize(attrTableSize + entryLength, 0);
563 pldm_bios_table_attr_entry_string_encode(
564 attributeTable.data() + attrTableSize, entryLength, &info);
Carol Wang612f35b2019-08-26 17:14:26 +0800565 }
Carol Wangdc220c82019-08-26 13:31:31 +0800566}
Carol Wangb503f9e2019-09-02 16:34:10 +0800567
John Wang3ad21752019-10-06 16:42:21 +0800568void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
569 const std::string& attrName,
Carol Wangb503f9e2019-09-02 16:34:10 +0800570 const BIOSTable& BIOSStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800571 Table& attrValueTable)
Carol Wangb503f9e2019-09-02 16:34:10 +0800572{
John Wang3ad21752019-10-06 16:42:21 +0800573 std::ignore = BIOSStringTable;
574 std::string currStr;
575 uint16_t currStrLen = 0;
576 try
Carol Wangb503f9e2019-09-02 16:34:10 +0800577 {
John Wang3ad21752019-10-06 16:42:21 +0800578 currStr = getAttrValue(attrName);
579 currStrLen = currStr.size();
Carol Wangb503f9e2019-09-02 16:34:10 +0800580 }
John Wang3ad21752019-10-06 16:42:21 +0800581 catch (const std::exception& e)
582 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600583 std::cerr << "getAttrValue returned error for attribute, NAME="
584 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800585 return;
586 }
587 auto entryLength =
588 pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
589 auto tableSize = attrValueTable.size();
590 attrValueTable.resize(tableSize + entryLength);
591 pldm_bios_table_attr_value_entry_encode_string(
592 attrValueTable.data() + tableSize, entryLength,
593 attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
594 currStr.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800595}
596
Carol Wangdc220c82019-08-26 13:31:31 +0800597} // end namespace bios_type_string
598
John Wangdbbc9ff2019-10-25 13:53:46 +0800599namespace bios_type_integer
600{
601
602using namespace bios_parser::bios_integer;
603
604/** @brief Construct the attibute table for BIOS type Integer and
605 * Integer ReadOnly
606 * @param[in] BIOSStringTable - the string table
607 * @param[in,out] attributeTable - the attribute table
608 *
609 */
610void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
611{
612 const auto& attributeMap = getValues();
613 StringHandle strHandle;
614 for (const auto& [key, value] : attributeMap)
615 {
616 try
617 {
618 strHandle = findStringHandle(key, BIOSStringTable);
619 }
620 catch (InternalFailure& e)
621 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600622 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
623 << key.c_str() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800624 continue;
625 }
626
627 const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
628 defaultValue] = value;
629 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
630
631 struct pldm_bios_table_attr_entry_integer_info info = {
632 strHandle, readOnly, lowerBound,
633 upperBound, scalarIncrement, defaultValue,
634 };
635 auto attrTableSize = attributeTable.size();
636 attributeTable.resize(attrTableSize + entryLength, 0);
637 pldm_bios_table_attr_entry_integer_encode(
638 attributeTable.data() + attrTableSize, entryLength, &info);
639 }
640}
641
642void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
643 const std::string& attrName,
644 const BIOSTable& BIOSStringTable,
645 Table& attrValueTable)
646{
647 std::ignore = BIOSStringTable;
648 uint64_t currentValue;
649 try
650 {
651 currentValue = getAttrValue(attrName);
652 }
653 catch (const std::exception& e)
654 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600655 std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
656 << " ERROR=" << e.what() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800657 return;
658 }
659 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
660 auto tableSize = attrValueTable.size();
661 attrValueTable.resize(tableSize + entryLength);
662 pldm_bios_table_attr_value_entry_encode_integer(
663 attrValueTable.data() + tableSize, entryLength,
664 attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
665}
666
667} // namespace bios_type_integer
668
John Wang02700402019-10-06 16:34:29 +0800669void traverseBIOSAttrTable(const Table& biosAttrTable,
670 AttrTableEntryHandler handler)
671{
672 std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
673 iter(pldm_bios_table_iter_create(biosAttrTable.data(),
674 biosAttrTable.size(),
675 PLDM_BIOS_ATTR_TABLE),
676 pldm_bios_table_iter_free);
677 while (!pldm_bios_table_iter_is_end(iter.get()))
678 {
679 auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
680 try
681 {
682 handler(table_entry);
683 }
684 catch (const std::exception& e)
685 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600686 std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
687 << e.what() << "\n";
John Wang02700402019-10-06 16:34:29 +0800688 }
689 pldm_bios_table_iter_next(iter.get());
690 }
691}
692
John Wange96e7e52019-10-05 17:47:30 +0800693using typeHandler = std::function<void(const BIOSTable& BIOSStringTable,
694 Table& attributeTable)>;
Carol Wangdc220c82019-08-26 13:31:31 +0800695std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
696 {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
John Wangdbbc9ff2019-10-25 13:53:46 +0800697 {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
698 {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
699};
Carol Wangdc220c82019-08-26 13:31:31 +0800700
Sampa Misrab37be312019-07-03 02:26:41 -0500701/** @brief Construct the BIOS attribute table
702 *
703 * @param[in] BIOSAttributeTable - the attribute table
704 * @param[in] BIOSStringTable - the string table
705 * @param[in] transferHandle - transfer handle to identify part of transfer
706 * @param[in] transferOpFlag - flag to indicate which part of data being
707 * transferred
708 * @param[in] instanceID - instance ID to identify the command
709 * @param[in] biosJsonDir - path where the BIOS json files are present
710 */
711Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
712 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500713 uint32_t /*transferHandle*/,
714 uint8_t /*transferOpFlag*/, uint8_t instanceID,
715 const char* biosJsonDir)
Sampa Misrab37be312019-07-03 02:26:41 -0500716{
717 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
718 0);
719 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
720 uint32_t nxtTransferHandle = 0;
721 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500722
723 if (BIOSAttributeTable.isEmpty())
724 { // no persisted table, constructing fresh table and response
Carol Wangdc220c82019-08-26 13:31:31 +0800725 Table attributeTable;
726 fs::path dir(biosJsonDir);
727
728 for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
729 it++)
730 {
731 fs::path file = dir / it->first;
732 if (fs::exists(file))
733 {
John Wange96e7e52019-10-05 17:47:30 +0800734 it->second(BIOSStringTable, attributeTable);
Carol Wangdc220c82019-08-26 13:31:31 +0800735 }
736 }
737
738 if (attributeTable.empty())
739 { // no available json file is found
740 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
741 nxtTransferHandle, transferFlag, nullptr,
742 response.size(), responsePtr);
743 return response;
744 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600745 pldm::responder::utils::padAndChecksum(attributeTable);
John Wangc2938352019-09-30 13:58:41 +0800746 BIOSAttributeTable.store(attributeTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500747 response.resize(sizeof(pldm_msg_hdr) +
748 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
749 attributeTable.size());
750 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500751 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
752 transferFlag, attributeTable.data(),
Carol Wangdc220c82019-08-26 13:31:31 +0800753 response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500754 }
755 else
756 { // persisted table present, constructing response
Sampa Misrab37be312019-07-03 02:26:41 -0500757 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
Carol Wangdc220c82019-08-26 13:31:31 +0800758 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500759 responsePtr); // filling up the header here
760 BIOSAttributeTable.load(response);
761 }
762
763 return response;
764}
765
John Wang3ad21752019-10-06 16:42:21 +0800766using AttrValTableEntryConstructHandler =
767 std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
768 const std::string& attrName,
769 const BIOSTable& BIOSStringTable, Table& table)>;
770
771using AttrType = uint8_t;
772const std::map<AttrType, AttrValTableEntryConstructHandler>
773 AttrValTableConstructMap{
774 {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
775 {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
776 {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
777 {PLDM_BIOS_ENUMERATION_READ_ONLY,
778 bios_type_enum::constructAttrValueEntry},
John Wangdbbc9ff2019-10-25 13:53:46 +0800779 {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
780 {PLDM_BIOS_INTEGER_READ_ONLY,
781 bios_type_integer::constructAttrValueEntry},
John Wang3ad21752019-10-06 16:42:21 +0800782 };
783
784void constructAttrValueTableEntry(
785 const struct pldm_bios_attr_table_entry* attrEntry,
786 const BIOSTable& BIOSStringTable, Table& attributeValueTable)
787{
788 auto attrName = findStringName(attrEntry->string_handle, BIOSStringTable);
789 if (attrName.empty())
790 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600791 std::cerr << "invalid string handle, STRING_HANDLE="
792 << attrEntry->string_handle << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800793 return;
794 }
795
796 AttrValTableConstructMap.at(attrEntry->attr_type)(
797 attrEntry, attrName, BIOSStringTable, attributeValueTable);
798}
799
Sampa Misrab37be312019-07-03 02:26:41 -0500800/** @brief Construct the BIOS attribute value table
801 *
802 * @param[in] BIOSAttributeValueTable - the attribute value table
803 * @param[in] BIOSAttributeTable - the attribute table
804 * @param[in] BIOSStringTable - the string table
805 * @param[in] transferHandle - transfer handle to identify part of transfer
806 * @param[in] transferOpFlag - flag to indicate which part of data being
807 * transferred
808 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500809 */
810Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
811 const BIOSTable& BIOSAttributeTable,
812 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500813 uint32_t& /*transferHandle*/,
814 uint8_t& /*transferOpFlag*/,
John Wang3ad21752019-10-06 16:42:21 +0800815 uint8_t instanceID)
Sampa Misrab37be312019-07-03 02:26:41 -0500816{
817 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
818 0);
819 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
820 uint32_t nxtTransferHandle = 0;
821 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500822
John Wang3ad21752019-10-06 16:42:21 +0800823 if (!BIOSAttributeValueTable.isEmpty())
824 {
Sampa Misrab37be312019-07-03 02:26:41 -0500825 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
John Wang3ad21752019-10-06 16:42:21 +0800826 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500827 responsePtr); // filling up the header here
828 BIOSAttributeValueTable.load(response);
John Wang3ad21752019-10-06 16:42:21 +0800829 return response;
Sampa Misrab37be312019-07-03 02:26:41 -0500830 }
831
John Wang3ad21752019-10-06 16:42:21 +0800832 Table attributeValueTable;
833 Table attributeTable;
834 BIOSAttributeTable.load(attributeTable);
835 traverseBIOSAttrTable(
836 attributeTable,
837 [&BIOSStringTable, &attributeValueTable](
838 const struct pldm_bios_attr_table_entry* tableEntry) {
839 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
840 attributeValueTable);
841 });
842 if (attributeValueTable.empty())
843 {
844 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
845 nxtTransferHandle, transferFlag, nullptr,
846 response.size(), responsePtr);
847 return response;
848 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600849 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800850 BIOSAttributeValueTable.store(attributeValueTable);
851
852 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
853 attributeValueTable.size());
854 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
855 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
856 transferFlag, attributeValueTable.data(),
857 response.size(), responsePtr);
858
Sampa Misrab37be312019-07-03 02:26:41 -0500859 return response;
860}
861
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600862Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
Sampa Misrab37be312019-07-03 02:26:41 -0500863{
Deepak Kodihallic3d20892019-08-01 05:38:31 -0500864 fs::create_directory(BIOS_TABLES_DIR);
Sampa Misrab37be312019-07-03 02:26:41 -0500865 auto response = internal::buildBIOSTables(request, payloadLength,
866 BIOS_JSONS_DIR, BIOS_TABLES_DIR);
867
868 return response;
869}
870
John Wang8721ed62019-12-05 14:44:43 +0800871Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
872 size_t payloadLength)
873{
874 uint32_t transferHandle;
875 uint8_t transferOpFlag;
876 uint16_t attributeHandle;
877
878 auto rc = decode_get_bios_attribute_current_value_by_handle_req(
879 request, payloadLength, &transferHandle, &transferOpFlag,
880 &attributeHandle);
881 if (rc != PLDM_SUCCESS)
882 {
883 return ccOnlyResponse(request, rc);
884 }
885
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600886 fs::path tablesPath(BIOS_TABLES_DIR);
887 auto stringTablePath = tablesPath / stringTableFile;
888 BIOSTable BIOSStringTable(stringTablePath.c_str());
889 auto attrTablePath = tablesPath / attrTableFile;
890 BIOSTable BIOSAttributeTable(attrTablePath.c_str());
891 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
892 {
893 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
894 }
895
896 auto attrValueTablePath = tablesPath / attrValTableFile;
897 BIOSTable BIOSAttributeValueTable(attrValueTablePath.c_str());
898
899 if (BIOSAttributeValueTable.isEmpty())
900 {
901 Table attributeValueTable;
902 Table attributeTable;
903 BIOSAttributeTable.load(attributeTable);
904 traverseBIOSAttrTable(
905 attributeTable,
906 [&BIOSStringTable, &attributeValueTable](
907 const struct pldm_bios_attr_table_entry* tableEntry) {
908 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
909 attributeValueTable);
910 });
911 if (attributeValueTable.empty())
912 {
913 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
914 }
915 pldm::responder::utils::padAndChecksum(attributeValueTable);
916 BIOSAttributeValueTable.store(attributeValueTable);
917 }
John Wang8721ed62019-12-05 14:44:43 +0800918
919 Response table;
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600920 BIOSAttributeValueTable.load(table);
John Wang8721ed62019-12-05 14:44:43 +0800921
922 auto entry = pldm_bios_table_attr_value_find_by_handle(
923 table.data(), table.size(), attributeHandle);
924 if (entry == nullptr)
925 {
926 return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
927 }
928
929 auto valueLength = pldm_bios_table_attr_value_entry_value_length(entry);
930 auto valuePtr = pldm_bios_table_attr_value_entry_value(entry);
931 Response response(sizeof(pldm_msg_hdr) +
932 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
933 valueLength,
934 0);
935 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
936 encode_get_bios_current_value_by_handle_resp(
937 request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END, valuePtr,
938 valueLength, responsePtr);
939
940 return response;
941}
942
Sampa Misrab37be312019-07-03 02:26:41 -0500943namespace internal
944{
945
946Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
947 const char* biosJsonDir, const char* biosTablePath)
948{
949 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
950 0);
951 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
952
John Wange96e7e52019-10-05 17:47:30 +0800953 if (setupConfig(biosJsonDir) != 0)
954 {
955 encode_get_bios_table_resp(
956 request->hdr.instance_id, PLDM_BIOS_TABLE_UNAVAILABLE,
957 0 /* nxtTransferHandle */, PLDM_START_AND_END, nullptr,
958 response.size(), responsePtr);
959 return response;
960 }
961
Sampa Misrab37be312019-07-03 02:26:41 -0500962 uint32_t transferHandle{};
963 uint8_t transferOpFlag{};
964 uint8_t tableType{};
965
966 auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
967 &transferOpFlag, &tableType);
968 if (rc == PLDM_SUCCESS)
969 {
970 BIOSTable BIOSStringTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600971 (std::string(biosTablePath) + "/" + stringTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500972 BIOSTable BIOSAttributeTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600973 (std::string(biosTablePath) + "/" + attrTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500974 BIOSTable BIOSAttributeValueTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600975 (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500976 switch (tableType)
977 {
978 case PLDM_BIOS_STRING_TABLE:
979
John Wange96e7e52019-10-05 17:47:30 +0800980 response = getBIOSStringTable(BIOSStringTable, transferHandle,
981 transferOpFlag,
982 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -0500983 break;
984 case PLDM_BIOS_ATTR_TABLE:
985
986 if (BIOSStringTable.isEmpty())
987 {
988 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
989 }
990 else
991 {
992 response = getBIOSAttributeTable(
993 BIOSAttributeTable, BIOSStringTable, transferHandle,
994 transferOpFlag, request->hdr.instance_id, biosJsonDir);
995 }
996 break;
997 case PLDM_BIOS_ATTR_VAL_TABLE:
Carol Wangf7d1a362019-11-18 15:34:14 +0800998 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
Sampa Misrab37be312019-07-03 02:26:41 -0500999 {
1000 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
1001 }
1002 else
1003 {
1004 response = getBIOSAttributeValueTable(
1005 BIOSAttributeValueTable, BIOSAttributeTable,
1006 BIOSStringTable, transferHandle, transferOpFlag,
John Wang3ad21752019-10-06 16:42:21 +08001007 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -05001008 }
1009 break;
1010 default:
1011 rc = PLDM_INVALID_BIOS_TABLE_TYPE;
1012 break;
1013 }
1014 }
1015
1016 if (rc != PLDM_SUCCESS)
1017 {
1018 uint32_t nxtTransferHandle{};
1019 uint8_t transferFlag{};
1020 size_t respPayloadLength{};
1021
1022 encode_get_bios_table_resp(request->hdr.instance_id, rc,
1023 nxtTransferHandle, transferFlag, nullptr,
1024 respPayloadLength, responsePtr);
1025 }
1026
1027 return response;
1028}
1029
1030} // end namespace internal
1031} // namespace bios
1032
Sampa Misra032bd502019-03-06 05:03:22 -06001033} // namespace responder
1034} // namespace pldm