blob: 2d3a8ee1d5ec8b1c8d891c17332fb19630b2c0f2 [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
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530160 encode_get_date_time_resp(request->hdr.instance_id, PLDM_ERROR, seconds,
161 minutes, hours, day, month, year,
162 responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500163 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600164 }
165
Sampa Misra032bd502019-03-06 05:03:22 -0600166 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
167 std::chrono::microseconds(timeUsec))
168 .count();
169
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600170 pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
171 day, month, year);
Sampa Misra032bd502019-03-06 05:03:22 -0600172
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530173 encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS, seconds,
174 minutes, hours, day, month, year, responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500175 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600176}
177
Xiaochao Ma60227a02019-12-04 09:00:12 +0800178Response Handler::setDateTime(const pldm_msg* request, size_t payloadLength)
179{
180 uint8_t seconds = 0;
181 uint8_t minutes = 0;
182 uint8_t hours = 0;
183 uint8_t day = 0;
184 uint8_t month = 0;
185 uint16_t year = 0;
186 std::time_t timeSec;
187
188 constexpr auto setTimeInterface = "xyz.openbmc_project.Time.EpochTime";
189 constexpr auto setTimePath = "/xyz/openbmc_project/time/host";
190 constexpr auto timeSetPro = "Elapsed";
191
192 auto rc = decode_set_date_time_req(request, payloadLength, &seconds,
193 &minutes, &hours, &day, &month, &year);
194 if (rc != PLDM_SUCCESS)
195 {
196 return ccOnlyResponse(request, rc);
197 }
198 timeSec = pldm::responder::utils::timeToEpoch(seconds, minutes, hours, day,
199 month, year);
200 uint64_t timeUsec = std::chrono::duration_cast<std::chrono::microseconds>(
201 std::chrono::seconds(timeSec))
202 .count();
203 std::variant<uint64_t> value{timeUsec};
204 try
205 {
206 pldm::utils::DBusHandler().setDbusProperty(setTimePath, timeSetPro,
207 setTimeInterface, value);
208 }
209 catch (std::exception& e)
210 {
211
212 std::cerr << "Error Setting time,PATH=" << setTimePath
213 << "TIME INTERFACE=" << setTimeInterface
214 << "ERROR=" << e.what() << "\n";
215
216 return ccOnlyResponse(request, PLDM_ERROR);
217 }
218
219 return ccOnlyResponse(request, PLDM_SUCCESS);
220}
221
Sampa Misrab37be312019-07-03 02:26:41 -0500222/** @brief Construct the BIOS string table
223 *
224 * @param[in] BIOSStringTable - the string table
225 * @param[in] transferHandle - transfer handle to identify part of transfer
226 * @param[in] transferOpFlag - flag to indicate which part of data being
227 * transferred
228 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500229 */
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500230Response getBIOSStringTable(BIOSTable& BIOSStringTable,
231 uint32_t /*transferHandle*/,
John Wange96e7e52019-10-05 17:47:30 +0800232 uint8_t /*transferOpFlag*/, uint8_t instanceID)
233
Sampa Misrab37be312019-07-03 02:26:41 -0500234{
235 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
236 0);
237 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
John Wangdd9a6282019-10-11 18:52:46 +0800238 if (!BIOSStringTable.isEmpty())
239 {
240 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS,
241 0, /* next transfer handle */
242 PLDM_START_AND_END, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500243 responsePtr); // filling up the header here
244 BIOSStringTable.load(response);
John Wangdd9a6282019-10-11 18:52:46 +0800245 return response;
246 }
247 auto biosStrings = bios_parser::getStrings();
248 std::sort(biosStrings.begin(), biosStrings.end());
249 // remove all duplicate strings received from bios json
250 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
251 biosStrings.end());
252
253 size_t sizeWithoutPad = std::accumulate(
254 biosStrings.begin(), biosStrings.end(), 0,
255 [](size_t sum, const std::string& elem) {
256 return sum +
257 pldm_bios_table_string_entry_encode_length(elem.length());
258 });
259
260 Table stringTable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600261 stringTable.reserve(
262 pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
John Wangdd9a6282019-10-11 18:52:46 +0800263
264 stringTable.resize(sizeWithoutPad);
265 auto tablePtr = stringTable.data();
266 for (const auto& elem : biosStrings)
267 {
268 auto entry_length =
269 pldm_bios_table_string_entry_encode_length(elem.length());
270 pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
271 elem.c_str(), elem.length());
272 tablePtr += entry_length;
273 sizeWithoutPad -= entry_length;
Sampa Misrab37be312019-07-03 02:26:41 -0500274 }
275
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600276 pldm::responder::utils::padAndChecksum(stringTable);
John Wangdd9a6282019-10-11 18:52:46 +0800277 BIOSStringTable.store(stringTable);
278 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
279 stringTable.size(),
280 0);
281 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
282 encode_get_bios_table_resp(
283 instanceID, PLDM_SUCCESS, 0 /* nxtTransferHandle */, PLDM_START_AND_END,
284 stringTable.data(), response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500285 return response;
286}
287
288/** @brief Find the string handle from the BIOS string table given the name
289 *
290 * @param[in] name - name of the BIOS string
291 * @param[in] BIOSStringTable - the string table
292 * @return - uint16_t - handle of the string
293 */
294StringHandle findStringHandle(const std::string& name,
295 const BIOSTable& BIOSStringTable)
296{
John Wangdd9a6282019-10-11 18:52:46 +0800297 Table table;
298 BIOSStringTable.load(table);
299 auto stringEntry = pldm_bios_table_string_find_by_string(
300 table.data(), table.size(), name.c_str());
301 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500302 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600303 std::cerr << "Reached end of BIOS string table,did not find the "
304 << "handle for the string, STRING=" << name.c_str() << "\n";
305 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500306 }
John Wangdd9a6282019-10-11 18:52:46 +0800307
308 return pldm_bios_table_string_entry_decode_handle(stringEntry);
Sampa Misrab37be312019-07-03 02:26:41 -0500309}
310
311/** @brief Find the string name from the BIOS string table for a string handle
312 *
313 * @param[in] stringHdl - string handle
314 * @param[in] BIOSStringTable - the string table
315 *
316 * @return - std::string - name of the corresponding BIOS string
317 */
318std::string findStringName(StringHandle stringHdl,
319 const BIOSTable& BIOSStringTable)
320{
John Wangdd9a6282019-10-11 18:52:46 +0800321 Table table;
322 BIOSStringTable.load(table);
323 auto stringEntry = pldm_bios_table_string_find_by_handle(
324 table.data(), table.size(), stringHdl);
Sampa Misrab37be312019-07-03 02:26:41 -0500325 std::string name;
John Wangdd9a6282019-10-11 18:52:46 +0800326 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500327 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600328 std::cerr << "Reached end of BIOS string table,did not find "
329 << "string name for handle, STRING_HANDLE=" << stringHdl
330 << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500331 }
John Wangdd9a6282019-10-11 18:52:46 +0800332 auto strLength =
333 pldm_bios_table_string_entry_decode_string_length(stringEntry);
334 name.resize(strLength);
335 pldm_bios_table_string_entry_decode_string(stringEntry, name.data(),
336 name.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500337 return name;
338}
339
340namespace bios_type_enum
341{
342
Carol Wangdc220c82019-08-26 13:31:31 +0800343using namespace bios_parser::bios_enum;
344
Sampa Misrab37be312019-07-03 02:26:41 -0500345/** @brief Find the indices into the array of the possible values of string
346 * handles for the current values.This is used in attribute value table
347 *
348 * @param[in] possiVals - vector of string handles comprising all the possible
349 * values for an attribute
350 * @param[in] currVals - vector of strings comprising all current values
351 * for an attribute
352 * @param[in] BIOSStringTable - the string table
353 *
354 * @return - std::vector<uint8_t> - indices into the array of the possible
355 * values of string handles
356 */
357std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
358 CurrentValues currVals,
359 const BIOSTable& BIOSStringTable)
360{
361 std::vector<uint8_t> stringIndices;
362
363 for (const auto& currVal : currVals)
364 {
365 StringHandle curHdl;
366 try
367 {
368 curHdl = findStringHandle(currVal, BIOSStringTable);
369 }
370 catch (InternalFailure& e)
371 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600372 std::cerr << "Exception fetching handle for the string, STRING="
373 << currVal.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500374 continue;
375 }
376
377 uint8_t i = 0;
378 for (auto possiHdl : possiVals)
379 {
380 if (possiHdl == curHdl)
381 {
382 stringIndices.push_back(i);
383 break;
384 }
385 i++;
386 }
387 }
388 return stringIndices;
389}
390
391/** @brief Find the indices into the array of the possible values of string
392 * handles for the default values. This is used in attribute table
393 *
394 * @param[in] possiVals - vector of strings comprising all the possible values
395 * for an attribute
396 * @param[in] defVals - vector of strings comprising all the default values
397 * for an attribute
398 * @return - std::vector<uint8_t> - indices into the array of the possible
399 * values of string
400 */
401std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
402 const DefaultValues& defVals)
403{
404 std::vector<uint8_t> defHdls;
405 for (const auto& defs : defVals)
406 {
407 auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
408 if (index != possiVals.end())
409 {
410 defHdls.push_back(index - possiVals.begin());
411 }
412 }
413
414 return defHdls;
415}
416
417/** @brief Construct the attibute table for BIOS type Enumeration and
418 * Enumeration ReadOnly
419 * @param[in] BIOSStringTable - the string table
420 * @param[in] biosJsonDir - path where the BIOS json files are present
Carol Wangdc220c82019-08-26 13:31:31 +0800421 * @param[in,out] attributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500422 *
Sampa Misrab37be312019-07-03 02:26:41 -0500423 */
John Wange96e7e52019-10-05 17:47:30 +0800424void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500425{
Sampa Misrab37be312019-07-03 02:26:41 -0500426 const auto& attributeMap = getValues();
Sampa Misrab37be312019-07-03 02:26:41 -0500427 StringHandle strHandle;
428
429 for (const auto& [key, value] : attributeMap)
430 {
431 try
432 {
433 strHandle = findStringHandle(key, BIOSStringTable);
434 }
435 catch (InternalFailure& e)
436 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600437 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
438 << key.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500439 continue;
440 }
John Wangccc04552019-10-14 14:28:25 +0800441 bool readOnly = (std::get<0>(value));
Sampa Misrab37be312019-07-03 02:26:41 -0500442 PossibleValues possiVals = std::get<1>(value);
443 DefaultValues defVals = std::get<2>(value);
444 // both the possible and default values are stored in sorted manner to
445 // ease in fetching back/comparison
446 std::sort(possiVals.begin(), possiVals.end());
447 std::sort(defVals.begin(), defVals.end());
448
449 std::vector<StringHandle> possiValsByHdl;
450 for (const auto& elem : possiVals)
451 {
452 try
453 {
454 auto hdl = findStringHandle(elem, BIOSStringTable);
455 possiValsByHdl.push_back(std::move(hdl));
456 }
457 catch (InternalFailure& e)
458 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600459 std::cerr << "Could not find handle for BIOS string, STRING="
460 << elem.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500461 continue;
462 }
463 }
464 auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
John Wangccc04552019-10-14 14:28:25 +0800465 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
466 possiValsByHdl.size(), defValsByHdl.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500467
John Wangccc04552019-10-14 14:28:25 +0800468 auto attrTableSize = attributeTable.size();
469 attributeTable.resize(attrTableSize + entryLength, 0);
470 struct pldm_bios_table_attr_entry_enum_info info = {
471 strHandle,
472 readOnly,
473 (uint8_t)possiValsByHdl.size(),
474 possiValsByHdl.data(),
475 (uint8_t)defValsByHdl.size(),
476 defValsByHdl.data(),
477 };
478 pldm_bios_table_attr_entry_enum_encode(
479 attributeTable.data() + attrTableSize, entryLength, &info);
Sampa Misrab37be312019-07-03 02:26:41 -0500480 }
Sampa Misrab37be312019-07-03 02:26:41 -0500481}
482
John Wang3ad21752019-10-06 16:42:21 +0800483void constructAttrValueEntry(
484 const struct pldm_bios_attr_table_entry* attrTableEntry,
485 const std::string& attrName, const BIOSTable& BIOSStringTable,
486 Table& attrValueTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500487{
John Wang3ad21752019-10-06 16:42:21 +0800488 CurrentValues currVals;
489 try
Sampa Misrab37be312019-07-03 02:26:41 -0500490 {
John Wang3ad21752019-10-06 16:42:21 +0800491 currVals = getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500492 }
John Wang3ad21752019-10-06 16:42:21 +0800493 catch (const std::exception& e)
494 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600495 std::cerr << "getAttrValue returned error for attribute, NAME="
496 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800497 return;
498 }
499 uint8_t pv_num =
500 pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
501 PossibleValuesByHandle pvHdls(pv_num, 0);
502 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
503 pvHdls.data(), pv_num);
504 std::sort(currVals.begin(), currVals.end());
505
506 auto currValStrIndices = findStrIndices(pvHdls, currVals, BIOSStringTable);
507
508 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
509 currValStrIndices.size());
510 auto tableSize = attrValueTable.size();
511 attrValueTable.resize(tableSize + entryLength);
512 pldm_bios_table_attr_value_entry_encode_enum(
513 attrValueTable.data() + tableSize, entryLength,
514 attrTableEntry->attr_handle, attrTableEntry->attr_type,
515 currValStrIndices.size(), currValStrIndices.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500516}
517
518} // end namespace bios_type_enum
519
Carol Wangdc220c82019-08-26 13:31:31 +0800520namespace bios_type_string
521{
Carol Wang612f35b2019-08-26 17:14:26 +0800522
523using namespace bios_parser::bios_string;
524
Carol Wangdc220c82019-08-26 13:31:31 +0800525/** @brief Construct the attibute table for BIOS type String and
526 * String ReadOnly
527 * @param[in] BIOSStringTable - the string table
528 * @param[in] biosJsonDir - path where the BIOS json files are present
529 * @param[in,out] attributeTable - the attribute table
530 *
531 */
John Wange96e7e52019-10-05 17:47:30 +0800532void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
Carol Wangdc220c82019-08-26 13:31:31 +0800533{
Carol Wang612f35b2019-08-26 17:14:26 +0800534 const auto& attributeMap = getValues();
535 StringHandle strHandle;
Carol Wang612f35b2019-08-26 17:14:26 +0800536 for (const auto& [key, value] : attributeMap)
537 {
538 try
539 {
540 strHandle = findStringHandle(key, BIOSStringTable);
541 }
542 catch (InternalFailure& e)
543 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600544 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
545 << key.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +0800546 continue;
547 }
548
John Wangccc04552019-10-14 14:28:25 +0800549 const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
Carol Wang612f35b2019-08-26 17:14:26 +0800550 defaultStr] = value;
John Wangccc04552019-10-14 14:28:25 +0800551 auto entryLength =
552 pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
Carol Wang612f35b2019-08-26 17:14:26 +0800553
John Wangccc04552019-10-14 14:28:25 +0800554 struct pldm_bios_table_attr_entry_string_info info = {
555 strHandle, readOnly, strType, minStrLen,
556 maxStrLen, defaultStrLen, defaultStr.data(),
557 };
558 auto attrTableSize = attributeTable.size();
559 attributeTable.resize(attrTableSize + entryLength, 0);
560 pldm_bios_table_attr_entry_string_encode(
561 attributeTable.data() + attrTableSize, entryLength, &info);
Carol Wang612f35b2019-08-26 17:14:26 +0800562 }
Carol Wangdc220c82019-08-26 13:31:31 +0800563}
Carol Wangb503f9e2019-09-02 16:34:10 +0800564
John Wang3ad21752019-10-06 16:42:21 +0800565void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
566 const std::string& attrName,
Carol Wangb503f9e2019-09-02 16:34:10 +0800567 const BIOSTable& BIOSStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800568 Table& attrValueTable)
Carol Wangb503f9e2019-09-02 16:34:10 +0800569{
John Wang3ad21752019-10-06 16:42:21 +0800570 std::ignore = BIOSStringTable;
571 std::string currStr;
572 uint16_t currStrLen = 0;
573 try
Carol Wangb503f9e2019-09-02 16:34:10 +0800574 {
John Wang3ad21752019-10-06 16:42:21 +0800575 currStr = getAttrValue(attrName);
576 currStrLen = currStr.size();
Carol Wangb503f9e2019-09-02 16:34:10 +0800577 }
John Wang3ad21752019-10-06 16:42:21 +0800578 catch (const std::exception& e)
579 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600580 std::cerr << "getAttrValue returned error for attribute, NAME="
581 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800582 return;
583 }
584 auto entryLength =
585 pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
586 auto tableSize = attrValueTable.size();
587 attrValueTable.resize(tableSize + entryLength);
588 pldm_bios_table_attr_value_entry_encode_string(
589 attrValueTable.data() + tableSize, entryLength,
590 attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
591 currStr.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800592}
593
Carol Wangdc220c82019-08-26 13:31:31 +0800594} // end namespace bios_type_string
595
John Wangdbbc9ff2019-10-25 13:53:46 +0800596namespace bios_type_integer
597{
598
599using namespace bios_parser::bios_integer;
600
601/** @brief Construct the attibute table for BIOS type Integer and
602 * Integer ReadOnly
603 * @param[in] BIOSStringTable - the string table
604 * @param[in,out] attributeTable - the attribute table
605 *
606 */
607void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
608{
609 const auto& attributeMap = getValues();
610 StringHandle strHandle;
611 for (const auto& [key, value] : attributeMap)
612 {
613 try
614 {
615 strHandle = findStringHandle(key, BIOSStringTable);
616 }
617 catch (InternalFailure& e)
618 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600619 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
620 << key.c_str() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800621 continue;
622 }
623
624 const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
625 defaultValue] = value;
626 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
627
628 struct pldm_bios_table_attr_entry_integer_info info = {
629 strHandle, readOnly, lowerBound,
630 upperBound, scalarIncrement, defaultValue,
631 };
632 auto attrTableSize = attributeTable.size();
633 attributeTable.resize(attrTableSize + entryLength, 0);
634 pldm_bios_table_attr_entry_integer_encode(
635 attributeTable.data() + attrTableSize, entryLength, &info);
636 }
637}
638
639void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
640 const std::string& attrName,
641 const BIOSTable& BIOSStringTable,
642 Table& attrValueTable)
643{
644 std::ignore = BIOSStringTable;
645 uint64_t currentValue;
646 try
647 {
648 currentValue = getAttrValue(attrName);
649 }
650 catch (const std::exception& e)
651 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600652 std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
653 << " ERROR=" << e.what() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800654 return;
655 }
656 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
657 auto tableSize = attrValueTable.size();
658 attrValueTable.resize(tableSize + entryLength);
659 pldm_bios_table_attr_value_entry_encode_integer(
660 attrValueTable.data() + tableSize, entryLength,
661 attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
662}
663
664} // namespace bios_type_integer
665
John Wang02700402019-10-06 16:34:29 +0800666void traverseBIOSAttrTable(const Table& biosAttrTable,
667 AttrTableEntryHandler handler)
668{
669 std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
670 iter(pldm_bios_table_iter_create(biosAttrTable.data(),
671 biosAttrTable.size(),
672 PLDM_BIOS_ATTR_TABLE),
673 pldm_bios_table_iter_free);
674 while (!pldm_bios_table_iter_is_end(iter.get()))
675 {
676 auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
677 try
678 {
679 handler(table_entry);
680 }
681 catch (const std::exception& e)
682 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600683 std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
684 << e.what() << "\n";
John Wang02700402019-10-06 16:34:29 +0800685 }
686 pldm_bios_table_iter_next(iter.get());
687 }
688}
689
John Wange96e7e52019-10-05 17:47:30 +0800690using typeHandler = std::function<void(const BIOSTable& BIOSStringTable,
691 Table& attributeTable)>;
Carol Wangdc220c82019-08-26 13:31:31 +0800692std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
693 {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
John Wangdbbc9ff2019-10-25 13:53:46 +0800694 {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
695 {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
696};
Carol Wangdc220c82019-08-26 13:31:31 +0800697
Sampa Misrab37be312019-07-03 02:26:41 -0500698/** @brief Construct the BIOS attribute table
699 *
700 * @param[in] BIOSAttributeTable - the attribute table
701 * @param[in] BIOSStringTable - the string table
702 * @param[in] transferHandle - transfer handle to identify part of transfer
703 * @param[in] transferOpFlag - flag to indicate which part of data being
704 * transferred
705 * @param[in] instanceID - instance ID to identify the command
706 * @param[in] biosJsonDir - path where the BIOS json files are present
707 */
708Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
709 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500710 uint32_t /*transferHandle*/,
711 uint8_t /*transferOpFlag*/, uint8_t instanceID,
712 const char* biosJsonDir)
Sampa Misrab37be312019-07-03 02:26:41 -0500713{
714 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
715 0);
716 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
717 uint32_t nxtTransferHandle = 0;
718 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500719
720 if (BIOSAttributeTable.isEmpty())
721 { // no persisted table, constructing fresh table and response
Carol Wangdc220c82019-08-26 13:31:31 +0800722 Table attributeTable;
723 fs::path dir(biosJsonDir);
724
725 for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
726 it++)
727 {
728 fs::path file = dir / it->first;
729 if (fs::exists(file))
730 {
John Wange96e7e52019-10-05 17:47:30 +0800731 it->second(BIOSStringTable, attributeTable);
Carol Wangdc220c82019-08-26 13:31:31 +0800732 }
733 }
734
735 if (attributeTable.empty())
736 { // no available json file is found
737 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
738 nxtTransferHandle, transferFlag, nullptr,
739 response.size(), responsePtr);
740 return response;
741 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600742 pldm::responder::utils::padAndChecksum(attributeTable);
John Wangc2938352019-09-30 13:58:41 +0800743 BIOSAttributeTable.store(attributeTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500744 response.resize(sizeof(pldm_msg_hdr) +
745 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
746 attributeTable.size());
747 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500748 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
749 transferFlag, attributeTable.data(),
Carol Wangdc220c82019-08-26 13:31:31 +0800750 response.size(), responsePtr);
Sampa Misrab37be312019-07-03 02:26:41 -0500751 }
752 else
753 { // persisted table present, constructing response
Sampa Misrab37be312019-07-03 02:26:41 -0500754 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
Carol Wangdc220c82019-08-26 13:31:31 +0800755 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500756 responsePtr); // filling up the header here
757 BIOSAttributeTable.load(response);
758 }
759
760 return response;
761}
762
John Wang3ad21752019-10-06 16:42:21 +0800763using AttrValTableEntryConstructHandler =
764 std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
765 const std::string& attrName,
766 const BIOSTable& BIOSStringTable, Table& table)>;
767
768using AttrType = uint8_t;
769const std::map<AttrType, AttrValTableEntryConstructHandler>
770 AttrValTableConstructMap{
771 {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
772 {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
773 {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
774 {PLDM_BIOS_ENUMERATION_READ_ONLY,
775 bios_type_enum::constructAttrValueEntry},
John Wangdbbc9ff2019-10-25 13:53:46 +0800776 {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
777 {PLDM_BIOS_INTEGER_READ_ONLY,
778 bios_type_integer::constructAttrValueEntry},
John Wang3ad21752019-10-06 16:42:21 +0800779 };
780
781void constructAttrValueTableEntry(
782 const struct pldm_bios_attr_table_entry* attrEntry,
783 const BIOSTable& BIOSStringTable, Table& attributeValueTable)
784{
785 auto attrName = findStringName(attrEntry->string_handle, BIOSStringTable);
786 if (attrName.empty())
787 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600788 std::cerr << "invalid string handle, STRING_HANDLE="
789 << attrEntry->string_handle << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800790 return;
791 }
792
793 AttrValTableConstructMap.at(attrEntry->attr_type)(
794 attrEntry, attrName, BIOSStringTable, attributeValueTable);
795}
796
Sampa Misrab37be312019-07-03 02:26:41 -0500797/** @brief Construct the BIOS attribute value table
798 *
799 * @param[in] BIOSAttributeValueTable - the attribute value table
800 * @param[in] BIOSAttributeTable - the attribute table
801 * @param[in] BIOSStringTable - the string table
802 * @param[in] transferHandle - transfer handle to identify part of transfer
803 * @param[in] transferOpFlag - flag to indicate which part of data being
804 * transferred
805 * @param[in] instanceID - instance ID to identify the command
Sampa Misrab37be312019-07-03 02:26:41 -0500806 */
807Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
808 const BIOSTable& BIOSAttributeTable,
809 const BIOSTable& BIOSStringTable,
Deepak Kodihalli3c275e12019-09-21 06:39:39 -0500810 uint32_t& /*transferHandle*/,
811 uint8_t& /*transferOpFlag*/,
John Wang3ad21752019-10-06 16:42:21 +0800812 uint8_t instanceID)
Sampa Misrab37be312019-07-03 02:26:41 -0500813{
814 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
815 0);
816 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
817 uint32_t nxtTransferHandle = 0;
818 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500819
John Wang3ad21752019-10-06 16:42:21 +0800820 if (!BIOSAttributeValueTable.isEmpty())
821 {
Sampa Misrab37be312019-07-03 02:26:41 -0500822 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
John Wang3ad21752019-10-06 16:42:21 +0800823 transferFlag, nullptr, response.size(),
Sampa Misrab37be312019-07-03 02:26:41 -0500824 responsePtr); // filling up the header here
825 BIOSAttributeValueTable.load(response);
John Wang3ad21752019-10-06 16:42:21 +0800826 return response;
Sampa Misrab37be312019-07-03 02:26:41 -0500827 }
828
John Wang3ad21752019-10-06 16:42:21 +0800829 Table attributeValueTable;
830 Table attributeTable;
831 BIOSAttributeTable.load(attributeTable);
832 traverseBIOSAttrTable(
833 attributeTable,
834 [&BIOSStringTable, &attributeValueTable](
835 const struct pldm_bios_attr_table_entry* tableEntry) {
836 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
837 attributeValueTable);
838 });
839 if (attributeValueTable.empty())
840 {
841 encode_get_bios_table_resp(instanceID, PLDM_BIOS_TABLE_UNAVAILABLE,
842 nxtTransferHandle, transferFlag, nullptr,
843 response.size(), responsePtr);
844 return response;
845 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600846 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800847 BIOSAttributeValueTable.store(attributeValueTable);
848
849 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
850 attributeValueTable.size());
851 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
852 encode_get_bios_table_resp(instanceID, PLDM_SUCCESS, nxtTransferHandle,
853 transferFlag, attributeValueTable.data(),
854 response.size(), responsePtr);
855
Sampa Misrab37be312019-07-03 02:26:41 -0500856 return response;
857}
858
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600859Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
Sampa Misrab37be312019-07-03 02:26:41 -0500860{
Deepak Kodihallic3d20892019-08-01 05:38:31 -0500861 fs::create_directory(BIOS_TABLES_DIR);
Sampa Misrab37be312019-07-03 02:26:41 -0500862 auto response = internal::buildBIOSTables(request, payloadLength,
863 BIOS_JSONS_DIR, BIOS_TABLES_DIR);
864
865 return response;
866}
867
John Wang8721ed62019-12-05 14:44:43 +0800868Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
869 size_t payloadLength)
870{
871 uint32_t transferHandle;
872 uint8_t transferOpFlag;
873 uint16_t attributeHandle;
874
875 auto rc = decode_get_bios_attribute_current_value_by_handle_req(
876 request, payloadLength, &transferHandle, &transferOpFlag,
877 &attributeHandle);
878 if (rc != PLDM_SUCCESS)
879 {
880 return ccOnlyResponse(request, rc);
881 }
882
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600883 fs::path tablesPath(BIOS_TABLES_DIR);
884 auto stringTablePath = tablesPath / stringTableFile;
885 BIOSTable BIOSStringTable(stringTablePath.c_str());
886 auto attrTablePath = tablesPath / attrTableFile;
887 BIOSTable BIOSAttributeTable(attrTablePath.c_str());
888 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
889 {
890 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
891 }
892
893 auto attrValueTablePath = tablesPath / attrValTableFile;
894 BIOSTable BIOSAttributeValueTable(attrValueTablePath.c_str());
895
896 if (BIOSAttributeValueTable.isEmpty())
897 {
898 Table attributeValueTable;
899 Table attributeTable;
900 BIOSAttributeTable.load(attributeTable);
901 traverseBIOSAttrTable(
902 attributeTable,
903 [&BIOSStringTable, &attributeValueTable](
904 const struct pldm_bios_attr_table_entry* tableEntry) {
905 constructAttrValueTableEntry(tableEntry, BIOSStringTable,
906 attributeValueTable);
907 });
908 if (attributeValueTable.empty())
909 {
910 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
911 }
912 pldm::responder::utils::padAndChecksum(attributeValueTable);
913 BIOSAttributeValueTable.store(attributeValueTable);
914 }
John Wang8721ed62019-12-05 14:44:43 +0800915
916 Response table;
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600917 BIOSAttributeValueTable.load(table);
John Wang8721ed62019-12-05 14:44:43 +0800918
919 auto entry = pldm_bios_table_attr_value_find_by_handle(
920 table.data(), table.size(), attributeHandle);
921 if (entry == nullptr)
922 {
923 return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
924 }
925
926 auto valueLength = pldm_bios_table_attr_value_entry_value_length(entry);
927 auto valuePtr = pldm_bios_table_attr_value_entry_value(entry);
928 Response response(sizeof(pldm_msg_hdr) +
929 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
930 valueLength,
931 0);
932 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
933 encode_get_bios_current_value_by_handle_resp(
934 request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END, valuePtr,
935 valueLength, responsePtr);
936
937 return response;
938}
939
Sampa Misrab37be312019-07-03 02:26:41 -0500940namespace internal
941{
942
943Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
944 const char* biosJsonDir, const char* biosTablePath)
945{
946 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
947 0);
948 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
949
John Wange96e7e52019-10-05 17:47:30 +0800950 if (setupConfig(biosJsonDir) != 0)
951 {
952 encode_get_bios_table_resp(
953 request->hdr.instance_id, PLDM_BIOS_TABLE_UNAVAILABLE,
954 0 /* nxtTransferHandle */, PLDM_START_AND_END, nullptr,
955 response.size(), responsePtr);
956 return response;
957 }
958
Sampa Misrab37be312019-07-03 02:26:41 -0500959 uint32_t transferHandle{};
960 uint8_t transferOpFlag{};
961 uint8_t tableType{};
962
963 auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
964 &transferOpFlag, &tableType);
965 if (rc == PLDM_SUCCESS)
966 {
967 BIOSTable BIOSStringTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600968 (std::string(biosTablePath) + "/" + stringTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500969 BIOSTable BIOSAttributeTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600970 (std::string(biosTablePath) + "/" + attrTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500971 BIOSTable BIOSAttributeValueTable(
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600972 (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
Sampa Misrab37be312019-07-03 02:26:41 -0500973 switch (tableType)
974 {
975 case PLDM_BIOS_STRING_TABLE:
976
John Wange96e7e52019-10-05 17:47:30 +0800977 response = getBIOSStringTable(BIOSStringTable, transferHandle,
978 transferOpFlag,
979 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -0500980 break;
981 case PLDM_BIOS_ATTR_TABLE:
982
983 if (BIOSStringTable.isEmpty())
984 {
985 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
986 }
987 else
988 {
989 response = getBIOSAttributeTable(
990 BIOSAttributeTable, BIOSStringTable, transferHandle,
991 transferOpFlag, request->hdr.instance_id, biosJsonDir);
992 }
993 break;
994 case PLDM_BIOS_ATTR_VAL_TABLE:
Carol Wangf7d1a362019-11-18 15:34:14 +0800995 if (BIOSAttributeTable.isEmpty() || BIOSStringTable.isEmpty())
Sampa Misrab37be312019-07-03 02:26:41 -0500996 {
997 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
998 }
999 else
1000 {
1001 response = getBIOSAttributeValueTable(
1002 BIOSAttributeValueTable, BIOSAttributeTable,
1003 BIOSStringTable, transferHandle, transferOpFlag,
John Wang3ad21752019-10-06 16:42:21 +08001004 request->hdr.instance_id);
Sampa Misrab37be312019-07-03 02:26:41 -05001005 }
1006 break;
1007 default:
1008 rc = PLDM_INVALID_BIOS_TABLE_TYPE;
1009 break;
1010 }
1011 }
1012
1013 if (rc != PLDM_SUCCESS)
1014 {
1015 uint32_t nxtTransferHandle{};
1016 uint8_t transferFlag{};
1017 size_t respPayloadLength{};
1018
1019 encode_get_bios_table_resp(request->hdr.instance_id, rc,
1020 nxtTransferHandle, transferFlag, nullptr,
1021 respPayloadLength, responsePtr);
1022 }
1023
1024 return response;
1025}
1026
1027} // end namespace internal
1028} // namespace bios
1029
Sampa Misra032bd502019-03-06 05:03:22 -06001030} // namespace responder
1031} // namespace pldm