blob: d815ce4faa8e80fa936e4f5a8c615c1ca5c7a0b3 [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "bios.hpp"
2
3#include "libpldmresponder/utils.hpp"
4#include "xyz/openbmc_project/Common/error.hpp"
5
6#include <array>
Sampa Misrab37be312019-07-03 02:26:41 -05007#include <boost/crc.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -06008#include <chrono>
9#include <ctime>
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060010#include <filesystem>
Sampa Misraaa8ae722019-12-12 03:20:40 -060011#include <iostream>
John Wang02700402019-10-06 16:34:29 +080012#include <memory>
Sampa Misrab37be312019-07-03 02:26:41 -050013#include <numeric>
Sampa Misra032bd502019-03-06 05:03:22 -060014#include <stdexcept>
15#include <string>
16#include <variant>
17#include <vector>
18
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060019namespace fs = std::filesystem;
Sampa Misrab37be312019-07-03 02:26:41 -050020using namespace pldm::responder::bios;
21using namespace bios_parser;
Sampa Misrab37be312019-07-03 02:26:41 -050022
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060023constexpr auto stringTableFile = "stringTable";
24constexpr auto attrTableFile = "attributeTable";
25constexpr auto attrValTableFile = "attributeValueTable";
26
Sampa Misra032bd502019-03-06 05:03:22 -060027namespace pldm
28{
29
Sampa Misrab37be312019-07-03 02:26:41 -050030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Sampa Misra032bd502019-03-06 05:03:22 -060031using EpochTimeUS = uint64_t;
Sampa Misrab37be312019-07-03 02:26:41 -050032using BIOSTableRow = std::vector<uint8_t>;
Carol Wangdc220c82019-08-26 13:31:31 +080033using BIOSJsonName = std::string;
Sampa Misra032bd502019-03-06 05:03:22 -060034
35constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
Sampa Misrab37be312019-07-03 02:26:41 -050036constexpr auto padChksumMax = 7;
Sampa Misra032bd502019-03-06 05:03:22 -060037
38namespace responder
39{
40
41namespace utils
42{
43
44void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
45 uint8_t& hours, uint8_t& day, uint8_t& month,
46 uint16_t& year)
47{
48 auto t = time_t(timeSec);
49 auto time = localtime(&t);
50
51 seconds = decimalToBcd(time->tm_sec);
52 minutes = decimalToBcd(time->tm_min);
53 hours = decimalToBcd(time->tm_hour);
54 day = decimalToBcd(time->tm_mday);
55 month =
56 decimalToBcd(time->tm_mon + 1); // The number of months in the range
57 // 0 to 11.PLDM expects range 1 to 12
58 year = decimalToBcd(time->tm_year + 1900); // The number of years since 1900
59}
60
John Wangc2938352019-09-30 13:58:41 +080061size_t getTableTotalsize(size_t sizeWithoutPad)
62{
John Wang79c37f12019-10-31 15:46:31 +080063 return sizeWithoutPad + pldm_bios_table_pad_checksum_size(sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080064}
65
66void padAndChecksum(Table& table)
67{
John Wang79c37f12019-10-31 15:46:31 +080068 auto sizeWithoutPad = table.size();
69 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
70 table.resize(table.size() + padAndChecksumSize);
John Wangc2938352019-09-30 13:58:41 +080071
John Wang79c37f12019-10-31 15:46:31 +080072 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
73 sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080074}
75
Sampa Misra032bd502019-03-06 05:03:22 -060076} // namespace utils
77
Deepak Kodihallibc669f12019-11-28 08:52:07 -060078namespace bios
79{
80
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060081Handler::Handler()
82{
83 try
84 {
85 fs::remove(
86 fs::path(std::string(BIOS_TABLES_DIR) + "/" + stringTableFile));
87 fs::remove(
88 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrTableFile));
89 fs::remove(
90 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrValTableFile));
91 }
92 catch (const std::exception& e)
93 {
94 }
95
96 handlers.emplace(PLDM_GET_DATE_TIME,
97 [this](const pldm_msg* request, size_t payloadLength) {
98 return this->getDateTime(request, payloadLength);
99 });
100 handlers.emplace(PLDM_GET_BIOS_TABLE,
101 [this](const pldm_msg* request, size_t payloadLength) {
102 return this->getBIOSTable(request, payloadLength);
103 });
John Wang8721ed62019-12-05 14:44:43 +0800104 handlers.emplace(PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
105 [this](const pldm_msg* request, size_t payloadLength) {
106 return this->getBIOSAttributeCurrentValueByHandle(
107 request, payloadLength);
108 });
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600109}
110
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600111Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
Sampa Misra032bd502019-03-06 05:03:22 -0600112{
113 uint8_t seconds = 0;
114 uint8_t minutes = 0;
115 uint8_t hours = 0;
116 uint8_t day = 0;
117 uint8_t month = 0;
118 uint16_t year = 0;
119
120 constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
George Liu408c3c42019-10-16 16:49:15 +0800121 constexpr auto hostTimePath = "/xyz/openbmc_project/time/host";
vkaverapa6575b82019-04-03 05:33:52 -0500122 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
123 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misra032bd502019-03-06 05:03:22 -0600124 std::variant<EpochTimeUS> value;
125
126 auto bus = sdbusplus::bus::new_default();
127 try
128 {
George Liu408c3c42019-10-16 16:49:15 +0800129 auto service = getService(bus, hostTimePath, timeInterface);
Sampa Misra032bd502019-03-06 05:03:22 -0600130
George Liu408c3c42019-10-16 16:49:15 +0800131 auto method = bus.new_method_call(service.c_str(), hostTimePath,
Sampa Misra032bd502019-03-06 05:03:22 -0600132 dbusProperties, "Get");
133 method.append(timeInterface, "Elapsed");
134
135 auto reply = bus.call(method);
136 reply.read(value);
137 }
138
139 catch (std::exception& e)
140 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600141 std::cerr << "Error getting time, PATH=" << hostTimePath
142 << " TIME INTERACE=" << timeInterface << "\n";
Sampa Misra032bd502019-03-06 05:03:22 -0600143
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530144 encode_get_date_time_resp(request->hdr.instance_id, PLDM_ERROR, seconds,
145 minutes, hours, day, month, year,
146 responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500147 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600148 }
149
150 uint64_t timeUsec = std::get<EpochTimeUS>(value);
151
152 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
153 std::chrono::microseconds(timeUsec))
154 .count();
155
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600156 pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
157 day, month, year);
Sampa Misra032bd502019-03-06 05:03:22 -0600158
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530159 encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS, seconds,
160 minutes, hours, day, month, year, responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500161 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600162}
163
Sampa Misrab37be312019-07-03 02:26:41 -0500164/** @brief Construct the BIOS string table
165 *
166 * @param[in] BIOSStringTable - the string table
167 * @param[in] transferHandle - transfer handle to identify part of transfer
168 * @param[in] transferOpFlag - flag to indicate which part of data being
169 * transferred
170 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500171 */
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500172Response getBIOSStringTable(BIOSTable& BIOSStringTable,
173 uint32_t /*transferHandle*/,
John Wange96e7e52019-10-05 17:47:30 +0800174 uint8_t /*transferOpFlag*/, uint8_t instanceID)
175
Sampa Misrab37be312019-07-03 02:26:41 -0500176{
177 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
178 0);
179 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
John Wangdd9a6282019-10-11 18:52:46 +0800180 if (!BIOSStringTable.isEmpty())
181 {
182 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS,
183 0, /* next transfer handle */
184 PLDM_START_AND_END, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500185 responsePtr); // filling up the header here
186 BIOSStringTable.load(response);
John Wangdd9a6282019-10-11 18:52:46 +0800187 return response;
188 }
189 auto biosStrings = bios_parser::getStrings();
190 std::sort(biosStrings.begin(), biosStrings.end());
191 // remove all duplicate strings received from bios json
192 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
193 biosStrings.end());
194
195 size_t sizeWithoutPad = std::accumulate(
196 biosStrings.begin(), biosStrings.end(), 0,
197 [](size_t sum, const std::string& elem) {
198 return sum +
199 pldm_bios_table_string_entry_encode_length(elem.length());
200 });
201
202 Table stringTable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600203 stringTable.reserve(
204 pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
John Wangdd9a6282019-10-11 18:52:46 +0800205
206 stringTable.resize(sizeWithoutPad);
207 auto tablePtr = stringTable.data();
208 for (const auto& elem : biosStrings)
209 {
210 auto entry_length =
211 pldm_bios_table_string_entry_encode_length(elem.length());
212 pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
213 elem.c_str(), elem.length());
214 tablePtr += entry_length;
215 sizeWithoutPad -= entry_length;
Sampa Misrab37be312019-07-03 02:26:41 -0500216 }
217
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600218 pldm::responder::utils::padAndChecksum(stringTable);
John Wangdd9a6282019-10-11 18:52:46 +0800219 BIOSStringTable.store(stringTable);
220 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
221 stringTable.size(),
222 0);
223 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
224 encode_get_bios_table_resp(
225 instanceID, PLDM_SUCCESS, 0 /* nxtTransferHandle */, PLDM_START_AND_END,
226 stringTable.data(), response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500227 return response;
228}
229
230/** @brief Find the string handle from the BIOS string table given the name
231 *
232 * @param[in] name - name of the BIOS string
233 * @param[in] BIOSStringTable - the string table
234 * @return - uint16_t - handle of the string
235 */
236StringHandle findStringHandle(const std::string& name,
237 const BIOSTable& BIOSStringTable)
238{
John Wangdd9a6282019-10-11 18:52:46 +0800239 Table table;
240 BIOSStringTable.load(table);
241 auto stringEntry = pldm_bios_table_string_find_by_string(
242 table.data(), table.size(), name.c_str());
243 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500244 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600245 std::cerr << "Reached end of BIOS string table,did not find the "
246 << "handle for the string, STRING=" << name.c_str() << "\n";
247 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500248 }
John Wangdd9a6282019-10-11 18:52:46 +0800249
250 return pldm_bios_table_string_entry_decode_handle(stringEntry);
Sampa Misrab37be312019-07-03 02:26:41 -0500251}
252
253/** @brief Find the string name from the BIOS string table for a string handle
254 *
255 * @param[in] stringHdl - string handle
256 * @param[in] BIOSStringTable - the string table
257 *
258 * @return - std::string - name of the corresponding BIOS string
259 */
260std::string findStringName(StringHandle stringHdl,
261 const BIOSTable& BIOSStringTable)
262{
John Wangdd9a6282019-10-11 18:52:46 +0800263 Table table;
264 BIOSStringTable.load(table);
265 auto stringEntry = pldm_bios_table_string_find_by_handle(
266 table.data(), table.size(), stringHdl);
Sampa Misrab37be312019-07-03 02:26:41 -0500267 std::string name;
John Wangdd9a6282019-10-11 18:52:46 +0800268 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500269 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600270 std::cerr << "Reached end of BIOS string table,did not find "
271 << "string name for handle, STRING_HANDLE=" << stringHdl
272 << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500273 }
John Wangdd9a6282019-10-11 18:52:46 +0800274 auto strLength =
275 pldm_bios_table_string_entry_decode_string_length(stringEntry);
276 name.resize(strLength);
277 pldm_bios_table_string_entry_decode_string(stringEntry, name.data(),
278 name.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500279 return name;
280}
281
282namespace bios_type_enum
283{
284
Carol Wangdc220c82019-08-26 13:31:31 +0800285using namespace bios_parser::bios_enum;
286
Sampa Misrab37be312019-07-03 02:26:41 -0500287/** @brief Find the indices into the array of the possible values of string
288 * handles for the current values.This is used in attribute value table
289 *
290 * @param[in] possiVals - vector of string handles comprising all the possible
291 * values for an attribute
292 * @param[in] currVals - vector of strings comprising all current values
293 * for an attribute
294 * @param[in] BIOSStringTable - the string table
295 *
296 * @return - std::vector<uint8_t> - indices into the array of the possible
297 * values of string handles
298 */
299std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
300 CurrentValues currVals,
301 const BIOSTable& BIOSStringTable)
302{
303 std::vector<uint8_t> stringIndices;
304
305 for (const auto& currVal : currVals)
306 {
307 StringHandle curHdl;
308 try
309 {
310 curHdl = findStringHandle(currVal, BIOSStringTable);
311 }
312 catch (InternalFailure& e)
313 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600314 std::cerr << "Exception fetching handle for the string, STRING="
315 << currVal.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500316 continue;
317 }
318
319 uint8_t i = 0;
320 for (auto possiHdl : possiVals)
321 {
322 if (possiHdl == curHdl)
323 {
324 stringIndices.push_back(i);
325 break;
326 }
327 i++;
328 }
329 }
330 return stringIndices;
331}
332
333/** @brief Find the indices into the array of the possible values of string
334 * handles for the default values. This is used in attribute table
335 *
336 * @param[in] possiVals - vector of strings comprising all the possible values
337 * for an attribute
338 * @param[in] defVals - vector of strings comprising all the default values
339 * for an attribute
340 * @return - std::vector<uint8_t> - indices into the array of the possible
341 * values of string
342 */
343std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
344 const DefaultValues& defVals)
345{
346 std::vector<uint8_t> defHdls;
347 for (const auto& defs : defVals)
348 {
349 auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
350 if (index != possiVals.end())
351 {
352 defHdls.push_back(index - possiVals.begin());
353 }
354 }
355
356 return defHdls;
357}
358
359/** @brief Construct the attibute table for BIOS type Enumeration and
360 * Enumeration ReadOnly
361 * @param[in] BIOSStringTable - the string table
362 * @param[in] biosJsonDir - path where the BIOS json files are present
Carol Wangdc220c82019-08-26 13:31:31 +0800363 * @param[in,out] attributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500364 *
Sampa Misrab37be312019-07-03 02:26:41 -0500365 */
John Wange96e7e52019-10-05 17:47:30 +0800366void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500367{
Sampa Misrab37be312019-07-03 02:26:41 -0500368 const auto& attributeMap = getValues();
Sampa Misrab37be312019-07-03 02:26:41 -0500369 StringHandle strHandle;
370
371 for (const auto& [key, value] : attributeMap)
372 {
373 try
374 {
375 strHandle = findStringHandle(key, BIOSStringTable);
376 }
377 catch (InternalFailure& e)
378 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600379 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
380 << key.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500381 continue;
382 }
John Wangccc04552019-10-14 14:28:25 +0800383 bool readOnly = (std::get<0>(value));
Sampa Misrab37be312019-07-03 02:26:41 -0500384 PossibleValues possiVals = std::get<1>(value);
385 DefaultValues defVals = std::get<2>(value);
386 // both the possible and default values are stored in sorted manner to
387 // ease in fetching back/comparison
388 std::sort(possiVals.begin(), possiVals.end());
389 std::sort(defVals.begin(), defVals.end());
390
391 std::vector<StringHandle> possiValsByHdl;
392 for (const auto& elem : possiVals)
393 {
394 try
395 {
396 auto hdl = findStringHandle(elem, BIOSStringTable);
397 possiValsByHdl.push_back(std::move(hdl));
398 }
399 catch (InternalFailure& e)
400 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600401 std::cerr << "Could not find handle for BIOS string, STRING="
402 << elem.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500403 continue;
404 }
405 }
406 auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
John Wangccc04552019-10-14 14:28:25 +0800407 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
408 possiValsByHdl.size(), defValsByHdl.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500409
John Wangccc04552019-10-14 14:28:25 +0800410 auto attrTableSize = attributeTable.size();
411 attributeTable.resize(attrTableSize + entryLength, 0);
412 struct pldm_bios_table_attr_entry_enum_info info = {
413 strHandle,
414 readOnly,
415 (uint8_t)possiValsByHdl.size(),
416 possiValsByHdl.data(),
417 (uint8_t)defValsByHdl.size(),
418 defValsByHdl.data(),
419 };
420 pldm_bios_table_attr_entry_enum_encode(
421 attributeTable.data() + attrTableSize, entryLength, &info);
Sampa Misrab37be312019-07-03 02:26:41 -0500422 }
Sampa Misrab37be312019-07-03 02:26:41 -0500423}
424
John Wang3ad21752019-10-06 16:42:21 +0800425void constructAttrValueEntry(
426 const struct pldm_bios_attr_table_entry* attrTableEntry,
427 const std::string& attrName, const BIOSTable& BIOSStringTable,
428 Table& attrValueTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500429{
John Wang3ad21752019-10-06 16:42:21 +0800430 CurrentValues currVals;
431 try
Sampa Misrab37be312019-07-03 02:26:41 -0500432 {
John Wang3ad21752019-10-06 16:42:21 +0800433 currVals = getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500434 }
John Wang3ad21752019-10-06 16:42:21 +0800435 catch (const std::exception& e)
436 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600437 std::cerr << "getAttrValue returned error for attribute, NAME="
438 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800439 return;
440 }
441 uint8_t pv_num =
442 pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
443 PossibleValuesByHandle pvHdls(pv_num, 0);
444 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
445 pvHdls.data(), pv_num);
446 std::sort(currVals.begin(), currVals.end());
447
448 auto currValStrIndices = findStrIndices(pvHdls, currVals, BIOSStringTable);
449
450 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
451 currValStrIndices.size());
452 auto tableSize = attrValueTable.size();
453 attrValueTable.resize(tableSize + entryLength);
454 pldm_bios_table_attr_value_entry_encode_enum(
455 attrValueTable.data() + tableSize, entryLength,
456 attrTableEntry->attr_handle, attrTableEntry->attr_type,
457 currValStrIndices.size(), currValStrIndices.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500458}
459
460} // end namespace bios_type_enum
461
Carol Wangdc220c82019-08-26 13:31:31 +0800462namespace bios_type_string
463{
Carol Wang612f35b2019-08-26 17:14:26 +0800464
465using namespace bios_parser::bios_string;
466
Carol Wangdc220c82019-08-26 13:31:31 +0800467/** @brief Construct the attibute table for BIOS type String and
468 * String ReadOnly
469 * @param[in] BIOSStringTable - the string table
470 * @param[in] biosJsonDir - path where the BIOS json files are present
471 * @param[in,out] attributeTable - the attribute table
472 *
473 */
John Wange96e7e52019-10-05 17:47:30 +0800474void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Carol Wangdc220c82019-08-26 13:31:31 +0800475{
Carol Wang612f35b2019-08-26 17:14:26 +0800476 const auto& attributeMap = getValues();
477 StringHandle strHandle;
Carol Wang612f35b2019-08-26 17:14:26 +0800478 for (const auto& [key, value] : attributeMap)
479 {
480 try
481 {
482 strHandle = findStringHandle(key, BIOSStringTable);
483 }
484 catch (InternalFailure& e)
485 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600486 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
487 << key.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +0800488 continue;
489 }
490
John Wangccc04552019-10-14 14:28:25 +0800491 const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
Carol Wang612f35b2019-08-26 17:14:26 +0800492 defaultStr] = value;
John Wangccc04552019-10-14 14:28:25 +0800493 auto entryLength =
494 pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
Carol Wang612f35b2019-08-26 17:14:26 +0800495
John Wangccc04552019-10-14 14:28:25 +0800496 struct pldm_bios_table_attr_entry_string_info info = {
497 strHandle, readOnly, strType, minStrLen,
498 maxStrLen, defaultStrLen, defaultStr.data(),
499 };
500 auto attrTableSize = attributeTable.size();
501 attributeTable.resize(attrTableSize + entryLength, 0);
502 pldm_bios_table_attr_entry_string_encode(
503 attributeTable.data() + attrTableSize, entryLength, &info);
Carol Wang612f35b2019-08-26 17:14:26 +0800504 }
Carol Wangdc220c82019-08-26 13:31:31 +0800505}
Carol Wangb503f9e2019-09-02 16:34:10 +0800506
John Wang3ad21752019-10-06 16:42:21 +0800507void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
508 const std::string& attrName,
Carol Wangb503f9e2019-09-02 16:34:10 +0800509 const BIOSTable& BIOSStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800510 Table& attrValueTable)
Carol Wangb503f9e2019-09-02 16:34:10 +0800511{
John Wang3ad21752019-10-06 16:42:21 +0800512 std::ignore = BIOSStringTable;
513 std::string currStr;
514 uint16_t currStrLen = 0;
515 try
Carol Wangb503f9e2019-09-02 16:34:10 +0800516 {
John Wang3ad21752019-10-06 16:42:21 +0800517 currStr = getAttrValue(attrName);
518 currStrLen = currStr.size();
Carol Wangb503f9e2019-09-02 16:34:10 +0800519 }
John Wang3ad21752019-10-06 16:42:21 +0800520 catch (const std::exception& e)
521 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600522 std::cerr << "getAttrValue returned error for attribute, NAME="
523 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800524 return;
525 }
526 auto entryLength =
527 pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
528 auto tableSize = attrValueTable.size();
529 attrValueTable.resize(tableSize + entryLength);
530 pldm_bios_table_attr_value_entry_encode_string(
531 attrValueTable.data() + tableSize, entryLength,
532 attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
533 currStr.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800534}
535
Carol Wangdc220c82019-08-26 13:31:31 +0800536} // end namespace bios_type_string
537
John Wangdbbc9ff2019-10-25 13:53:46 +0800538namespace bios_type_integer
539{
540
541using namespace bios_parser::bios_integer;
542
543/** @brief Construct the attibute table for BIOS type Integer and
544 * Integer ReadOnly
545 * @param[in] BIOSStringTable - the string table
546 * @param[in,out] attributeTable - the attribute table
547 *
548 */
549void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
550{
551 const auto& attributeMap = getValues();
552 StringHandle strHandle;
553 for (const auto& [key, value] : attributeMap)
554 {
555 try
556 {
557 strHandle = findStringHandle(key, BIOSStringTable);
558 }
559 catch (InternalFailure& e)
560 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600561 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
562 << key.c_str() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800563 continue;
564 }
565
566 const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
567 defaultValue] = value;
568 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
569
570 struct pldm_bios_table_attr_entry_integer_info info = {
571 strHandle, readOnly, lowerBound,
572 upperBound, scalarIncrement, defaultValue,
573 };
574 auto attrTableSize = attributeTable.size();
575 attributeTable.resize(attrTableSize + entryLength, 0);
576 pldm_bios_table_attr_entry_integer_encode(
577 attributeTable.data() + attrTableSize, entryLength, &info);
578 }
579}
580
581void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
582 const std::string& attrName,
583 const BIOSTable& BIOSStringTable,
584 Table& attrValueTable)
585{
586 std::ignore = BIOSStringTable;
587 uint64_t currentValue;
588 try
589 {
590 currentValue = getAttrValue(attrName);
591 }
592 catch (const std::exception& e)
593 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600594 std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
595 << " ERROR=" << e.what() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800596 return;
597 }
598 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
599 auto tableSize = attrValueTable.size();
600 attrValueTable.resize(tableSize + entryLength);
601 pldm_bios_table_attr_value_entry_encode_integer(
602 attrValueTable.data() + tableSize, entryLength,
603 attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
604}
605
606} // namespace bios_type_integer
607
John Wang02700402019-10-06 16:34:29 +0800608void traverseBIOSAttrTable(const Table& biosAttrTable,
609 AttrTableEntryHandler handler)
610{
611 std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
612 iter(pldm_bios_table_iter_create(biosAttrTable.data(),
613 biosAttrTable.size(),
614 PLDM_BIOS_ATTR_TABLE),
615 pldm_bios_table_iter_free);
616 while (!pldm_bios_table_iter_is_end(iter.get()))
617 {
618 auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
619 try
620 {
621 handler(table_entry);
622 }
623 catch (const std::exception& e)
624 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600625 std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
626 << e.what() << "\n";
John Wang02700402019-10-06 16:34:29 +0800627 }
628 pldm_bios_table_iter_next(iter.get());
629 }
630}
631
John Wange96e7e52019-10-05 17:47:30 +0800632using typeHandler = std::function<void(const BIOSTable& BIOSStringTable,
633 Table& attributeTable)>;
Carol Wangdc220c82019-08-26 13:31:31 +0800634std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
635 {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
John Wangdbbc9ff2019-10-25 13:53:46 +0800636 {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
637 {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
638};
Carol Wangdc220c82019-08-26 13:31:31 +0800639
Sampa Misrab37be312019-07-03 02:26:41 -0500640/** @brief Construct the BIOS attribute table
641 *
642 * @param[in] BIOSAttributeTable - the attribute table
643 * @param[in] BIOSStringTable - the string table
644 * @param[in] transferHandle - transfer handle to identify part of transfer
645 * @param[in] transferOpFlag - flag to indicate which part of data being
646 * transferred
647 * @param[in] instanceID - instance ID to identify the command
648 * @param[in] biosJsonDir - path where the BIOS json files are present
649 */
650Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
651 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500652 uint32_t /*transferHandle*/,
653 uint8_t /*transferOpFlag*/, uint8_t instanceID,
654 const char* biosJsonDir)
Sampa Misrab37be312019-07-03 02:26:41 -0500655{
656 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
657 0);
658 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
659 uint32_t nxtTransferHandle = 0;
660 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500661
662 if (BIOSAttributeTable.isEmpty())
663 { // no persisted table, constructing fresh table and response
Carol Wangdc220c82019-08-26 13:31:31 +0800664 Table attributeTable;
665 fs::path dir(biosJsonDir);
666
667 for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
668 it++)
669 {
670 fs::path file = dir / it->first;
671 if (fs::exists(file))
672 {
John Wange96e7e52019-10-05 17:47:30 +0800673 it->second(BIOSStringTable, attributeTable);
Carol Wangdc220c82019-08-26 13:31:31 +0800674 }
675 }
676
677 if (attributeTable.empty())
678 { // no available json file is found
679 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
680 nxtTransferHandle, transferFlag, nullptr,
681 response.size(), responsePtr);
682 return response;
683 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600684 pldm::responder::utils::padAndChecksum(attributeTable);
John Wangc2938352019-09-30 13:58:41 +0800685 BIOSAttributeTable.store(attributeTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500686 response.resize(sizeof(pldm_msg_hdr) +
687 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
688 attributeTable.size());
689 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500690 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
691 transferFlag, attributeTable.data(),
Carol Wangdc220c82019-08-26 13:31:31 +0800692 response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500693 }
694 else
695 { // persisted table present, constructing response
Sampa Misrab37be312019-07-03 02:26:41 -0500696 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
Carol Wangdc220c82019-08-26 13:31:31 +0800697 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500698 responsePtr); // filling up the header here
699 BIOSAttributeTable.load(response);
700 }
701
702 return response;
703}
704
John Wang3ad21752019-10-06 16:42:21 +0800705using AttrValTableEntryConstructHandler =
706 std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
707 const std::string& attrName,
708 const BIOSTable& BIOSStringTable, Table& table)>;
709
710using AttrType = uint8_t;
711const std::map<AttrType, AttrValTableEntryConstructHandler>
712 AttrValTableConstructMap{
713 {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
714 {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
715 {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
716 {PLDM_BIOS_ENUMERATION_READ_ONLY,
717 bios_type_enum::constructAttrValueEntry},
John Wangdbbc9ff2019-10-25 13:53:46 +0800718 {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
719 {PLDM_BIOS_INTEGER_READ_ONLY,
720 bios_type_integer::constructAttrValueEntry},
John Wang3ad21752019-10-06 16:42:21 +0800721 };
722
723void constructAttrValueTableEntry(
724 const struct pldm_bios_attr_table_entry* attrEntry,
725 const BIOSTable& BIOSStringTable, Table& attributeValueTable)
726{
727 auto attrName = findStringName(attrEntry->string_handle, BIOSStringTable);
728 if (attrName.empty())
729 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600730 std::cerr << "invalid string handle, STRING_HANDLE="
731 << attrEntry->string_handle << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800732 return;
733 }
734
735 AttrValTableConstructMap.at(attrEntry->attr_type)(
736 attrEntry, attrName, BIOSStringTable, attributeValueTable);
737}
738
Sampa Misrab37be312019-07-03 02:26:41 -0500739/** @brief Construct the BIOS attribute value table
740 *
741 * @param[in] BIOSAttributeValueTable - the attribute value table
742 * @param[in] BIOSAttributeTable - the attribute table
743 * @param[in] BIOSStringTable - the string table
744 * @param[in] transferHandle - transfer handle to identify part of transfer
745 * @param[in] transferOpFlag - flag to indicate which part of data being
746 * transferred
747 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500748 */
749Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
750 const BIOSTable& BIOSAttributeTable,
751 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500752 uint32_t& /*transferHandle*/,
753 uint8_t& /*transferOpFlag*/,
John Wang3ad21752019-10-06 16:42:21 +0800754 uint8_t instanceID)
Sampa Misrab37be312019-07-03 02:26:41 -0500755{
756 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
757 0);
758 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
759 uint32_t nxtTransferHandle = 0;
760 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500761
John Wang3ad21752019-10-06 16:42:21 +0800762 if (!BIOSAttributeValueTable.isEmpty())
763 {
Sampa Misrab37be312019-07-03 02:26:41 -0500764 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
John Wang3ad21752019-10-06 16:42:21 +0800765 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500766 responsePtr); // filling up the header here
767 BIOSAttributeValueTable.load(response);
John Wang3ad21752019-10-06 16:42:21 +0800768 return response;
Sampa Misrab37be312019-07-03 02:26:41 -0500769 }
770
John Wang3ad21752019-10-06 16:42:21 +0800771 Table attributeValueTable;
772 Table attributeTable;
773 BIOSAttributeTable.load(attributeTable);
774 traverseBIOSAttrTable(
775 attributeTable,
776 [&BIOSStringTable, &attributeValueTable](
777 const struct pldm_bios_attr_table_entry* tableEntry) {
778 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
779 attributeValueTable);
780 });
781 if (attributeValueTable.empty())
782 {
783 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
784 nxtTransferHandle, transferFlag, nullptr,
785 response.size(), responsePtr);
786 return response;
787 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600788 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800789 BIOSAttributeValueTable.store(attributeValueTable);
790
791 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
792 attributeValueTable.size());
793 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
794 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
795 transferFlag, attributeValueTable.data(),
796 response.size(), responsePtr);
797
Sampa Misrab37be312019-07-03 02:26:41 -0500798 return response;
799}
800
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600801Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
Sampa Misrab37be312019-07-03 02:26:41 -0500802{
Deepak Kodihallic3d20892019-08-01 05:38:31 -0500803 fs::create_directory(BIOS_TABLES_DIR);
Sampa Misrab37be312019-07-03 02:26:41 -0500804 auto response = internal::buildBIOSTables(request, payloadLength,
805 BIOS_JSONS_DIR, BIOS_TABLES_DIR);
806
807 return response;
808}
809
John Wang8721ed62019-12-05 14:44:43 +0800810Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
811 size_t payloadLength)
812{
813 uint32_t transferHandle;
814 uint8_t transferOpFlag;
815 uint16_t attributeHandle;
816
817 auto rc = decode_get_bios_attribute_current_value_by_handle_req(
818 request, payloadLength, &transferHandle, &transferOpFlag,
819 &attributeHandle);
820 if (rc != PLDM_SUCCESS)
821 {
822 return ccOnlyResponse(request, rc);
823 }
824
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600825 fs::path tablesPath(BIOS_TABLES_DIR);
826 auto stringTablePath = tablesPath / stringTableFile;
827 BIOSTable BIOSStringTable(stringTablePath.c_str());
828 auto attrTablePath = tablesPath / attrTableFile;
829 BIOSTable BIOSAttributeTable(attrTablePath.c_str());
830 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
831 {
832 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
833 }
834
835 auto attrValueTablePath = tablesPath / attrValTableFile;
836 BIOSTable BIOSAttributeValueTable(attrValueTablePath.c_str());
837
838 if (BIOSAttributeValueTable.isEmpty())
839 {
840 Table attributeValueTable;
841 Table attributeTable;
842 BIOSAttributeTable.load(attributeTable);
843 traverseBIOSAttrTable(
844 attributeTable,
845 [&BIOSStringTable, &attributeValueTable](
846 const struct pldm_bios_attr_table_entry* tableEntry) {
847 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
848 attributeValueTable);
849 });
850 if (attributeValueTable.empty())
851 {
852 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
853 }
854 pldm::responder::utils::padAndChecksum(attributeValueTable);
855 BIOSAttributeValueTable.store(attributeValueTable);
856 }
John Wang8721ed62019-12-05 14:44:43 +0800857
858 Response table;
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600859 BIOSAttributeValueTable.load(table);
John Wang8721ed62019-12-05 14:44:43 +0800860
861 auto entry = pldm_bios_table_attr_value_find_by_handle(
862 table.data(), table.size(), attributeHandle);
863 if (entry == nullptr)
864 {
865 return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
866 }
867
868 auto valueLength = pldm_bios_table_attr_value_entry_value_length(entry);
869 auto valuePtr = pldm_bios_table_attr_value_entry_value(entry);
870 Response response(sizeof(pldm_msg_hdr) +
871 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
872 valueLength,
873 0);
874 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
875 encode_get_bios_current_value_by_handle_resp(
876 request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END, valuePtr,
877 valueLength, responsePtr);
878
879 return response;
880}
881
Sampa Misrab37be312019-07-03 02:26:41 -0500882namespace internal
883{
884
885Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
886 const char* biosJsonDir, const char* biosTablePath)
887{
888 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
889 0);
890 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
891
John Wange96e7e52019-10-05 17:47:30 +0800892 if (setupConfig(biosJsonDir) != 0)
893 {
894 encode_get_bios_table_resp(
895 request->hdr.instance_id, PLDM_BIOS_TABLE_UNAVAILABLE,
896 0 /* nxtTransferHandle */, PLDM_START_AND_END, nullptr,
897 response.size(), responsePtr);
898 return response;
899 }
900
Sampa Misrab37be312019-07-03 02:26:41 -0500901 uint32_t transferHandle{};
902 uint8_t transferOpFlag{};
903 uint8_t tableType{};
904
905 auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
906 &transferOpFlag, &tableType);
907 if (rc == PLDM_SUCCESS)
908 {
909 BIOSTable BIOSStringTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600910 (std::string(biosTablePath) + "/" + stringTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500911 BIOSTable BIOSAttributeTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600912 (std::string(biosTablePath) + "/" + attrTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500913 BIOSTable BIOSAttributeValueTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600914 (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500915 switch (tableType)
916 {
917 case PLDM_BIOS_STRING_TABLE:
918
John Wange96e7e52019-10-05 17:47:30 +0800919 response = getBIOSStringTable(BIOSStringTable, transferHandle,
920 transferOpFlag,
921 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -0500922 break;
923 case PLDM_BIOS_ATTR_TABLE:
924
925 if (BIOSStringTable.isEmpty())
926 {
927 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
928 }
929 else
930 {
931 response = getBIOSAttributeTable(
932 BIOSAttributeTable, BIOSStringTable, transferHandle,
933 transferOpFlag, request->hdr.instance_id, biosJsonDir);
934 }
935 break;
936 case PLDM_BIOS_ATTR_VAL_TABLE:
Carol Wangf7d1a362019-11-18 15:34:14 +0800937 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
Sampa Misrab37be312019-07-03 02:26:41 -0500938 {
939 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
940 }
941 else
942 {
943 response = getBIOSAttributeValueTable(
944 BIOSAttributeValueTable, BIOSAttributeTable,
945 BIOSStringTable, transferHandle, transferOpFlag,
John Wang3ad21752019-10-06 16:42:21 +0800946 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -0500947 }
948 break;
949 default:
950 rc = PLDM_INVALID_BIOS_TABLE_TYPE;
951 break;
952 }
953 }
954
955 if (rc != PLDM_SUCCESS)
956 {
957 uint32_t nxtTransferHandle{};
958 uint8_t transferFlag{};
959 size_t respPayloadLength{};
960
961 encode_get_bios_table_resp(request->hdr.instance_id, rc,
962 nxtTransferHandle, transferFlag, nullptr,
963 respPayloadLength, responsePtr);
964 }
965
966 return response;
967}
968
969} // end namespace internal
970} // namespace bios
971
Sampa Misra032bd502019-03-06 05:03:22 -0600972} // namespace responder
973} // namespace pldm