blob: 082ac0fc8033259791d069a9fe2f054bc882ffe9 [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "bios.hpp"
2
George Liu83409572019-12-24 18:42:54 +08003#include "utils.hpp"
Sampa Misra032bd502019-03-06 05:03:22 -06004#include "xyz/openbmc_project/Common/error.hpp"
5
Xiaochao Ma60227a02019-12-04 09:00:12 +08006#include <time.h>
7
Sampa Misra032bd502019-03-06 05:03:22 -06008#include <array>
Sampa Misrab37be312019-07-03 02:26:41 -05009#include <boost/crc.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -060010#include <chrono>
11#include <ctime>
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060012#include <filesystem>
Sampa Misraaa8ae722019-12-12 03:20:40 -060013#include <iostream>
John Wang02700402019-10-06 16:34:29 +080014#include <memory>
Sampa Misrab37be312019-07-03 02:26:41 -050015#include <numeric>
Sampa Misra032bd502019-03-06 05:03:22 -060016#include <stdexcept>
17#include <string>
18#include <variant>
19#include <vector>
20
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060021namespace fs = std::filesystem;
Sampa Misrab37be312019-07-03 02:26:41 -050022using namespace pldm::responder::bios;
23using namespace bios_parser;
Sampa Misrab37be312019-07-03 02:26:41 -050024
Deepak Kodihallid9fb1522019-11-28 10:06:34 -060025constexpr auto stringTableFile = "stringTable";
26constexpr auto attrTableFile = "attributeTable";
27constexpr auto attrValTableFile = "attributeValueTable";
28
Sampa Misra032bd502019-03-06 05:03:22 -060029namespace pldm
30{
31
Sampa Misrab37be312019-07-03 02:26:41 -050032using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Sampa Misra032bd502019-03-06 05:03:22 -060033using EpochTimeUS = uint64_t;
Sampa Misrab37be312019-07-03 02:26:41 -050034using BIOSTableRow = std::vector<uint8_t>;
Carol Wangdc220c82019-08-26 13:31:31 +080035using BIOSJsonName = std::string;
Sampa Misra032bd502019-03-06 05:03:22 -060036
37constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
Sampa Misrab37be312019-07-03 02:26:41 -050038constexpr auto padChksumMax = 7;
Sampa Misra032bd502019-03-06 05:03:22 -060039
40namespace responder
41{
42
43namespace utils
44{
45
46void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
47 uint8_t& hours, uint8_t& day, uint8_t& month,
48 uint16_t& year)
49{
50 auto t = time_t(timeSec);
51 auto time = localtime(&t);
52
George Liu83409572019-12-24 18:42:54 +080053 seconds = pldm::utils::decimalToBcd(time->tm_sec);
54 minutes = pldm::utils::decimalToBcd(time->tm_min);
55 hours = pldm::utils::decimalToBcd(time->tm_hour);
56 day = pldm::utils::decimalToBcd(time->tm_mday);
57 month = pldm::utils::decimalToBcd(time->tm_mon +
58 1); // The number of months in the range
59 // 0 to 11.PLDM expects range 1 to 12
60 year = pldm::utils::decimalToBcd(time->tm_year +
61 1900); // The number of years since 1900
Sampa Misra032bd502019-03-06 05:03:22 -060062}
63
Xiaochao Ma60227a02019-12-04 09:00:12 +080064std::time_t timeToEpoch(uint8_t seconds, uint8_t minutes, uint8_t hours,
65 uint8_t day, uint8_t month, uint16_t year)
66{
67 struct std::tm stm;
68
69 stm.tm_year = year - 1900;
70 stm.tm_mon = month - 1;
71 stm.tm_mday = day;
72 stm.tm_hour = hours;
73 stm.tm_min = minutes;
74 stm.tm_sec = seconds;
75 stm.tm_isdst = -1;
76
77 // It will get the time in seconds since
78 // Epoch, 1970.1.1 00:00:00 +0000,UTC.
79 return timegm(&stm);
80}
81
John Wangc2938352019-09-30 13:58:41 +080082size_t getTableTotalsize(size_t sizeWithoutPad)
83{
John Wang79c37f12019-10-31 15:46:31 +080084 return sizeWithoutPad + pldm_bios_table_pad_checksum_size(sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080085}
86
87void padAndChecksum(Table& table)
88{
John Wang79c37f12019-10-31 15:46:31 +080089 auto sizeWithoutPad = table.size();
90 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
91 table.resize(table.size() + padAndChecksumSize);
John Wangc2938352019-09-30 13:58:41 +080092
John Wang79c37f12019-10-31 15:46:31 +080093 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
94 sizeWithoutPad);
John Wangc2938352019-09-30 13:58:41 +080095}
96
Sampa Misra032bd502019-03-06 05:03:22 -060097} // namespace utils
98
Deepak Kodihallibc669f12019-11-28 08:52:07 -060099namespace bios
100{
101
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600102Handler::Handler()
103{
104 try
105 {
106 fs::remove(
107 fs::path(std::string(BIOS_TABLES_DIR) + "/" + stringTableFile));
108 fs::remove(
109 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrTableFile));
110 fs::remove(
111 fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrValTableFile));
112 }
113 catch (const std::exception& e)
114 {
115 }
Xiaochao Ma60227a02019-12-04 09:00:12 +0800116 handlers.emplace(PLDM_SET_DATE_TIME,
117 [this](const pldm_msg* request, size_t payloadLength) {
118 return this->setDateTime(request, payloadLength);
119 });
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600120 handlers.emplace(PLDM_GET_DATE_TIME,
121 [this](const pldm_msg* request, size_t payloadLength) {
122 return this->getDateTime(request, payloadLength);
123 });
124 handlers.emplace(PLDM_GET_BIOS_TABLE,
125 [this](const pldm_msg* request, size_t payloadLength) {
126 return this->getBIOSTable(request, payloadLength);
127 });
John Wang8721ed62019-12-05 14:44:43 +0800128 handlers.emplace(PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
129 [this](const pldm_msg* request, size_t payloadLength) {
130 return this->getBIOSAttributeCurrentValueByHandle(
131 request, payloadLength);
132 });
Deepak Kodihallid9fb1522019-11-28 10:06:34 -0600133}
134
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600135Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
Sampa Misra032bd502019-03-06 05:03:22 -0600136{
137 uint8_t seconds = 0;
138 uint8_t minutes = 0;
139 uint8_t hours = 0;
140 uint8_t day = 0;
141 uint8_t month = 0;
142 uint16_t year = 0;
143
144 constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
George Liu408c3c42019-10-16 16:49:15 +0800145 constexpr auto hostTimePath = "/xyz/openbmc_project/time/host";
vkaverapa6575b82019-04-03 05:33:52 -0500146 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
147 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liu782d37f2020-01-24 09:02:17 +0800148 EpochTimeUS timeUsec;
Sampa Misra032bd502019-03-06 05:03:22 -0600149
Sampa Misra032bd502019-03-06 05:03:22 -0600150 try
151 {
George Liu782d37f2020-01-24 09:02:17 +0800152 timeUsec = pldm::utils::DBusHandler().getDbusProperty<EpochTimeUS>(
153 hostTimePath, "Elapsed", timeInterface);
Sampa Misra032bd502019-03-06 05:03:22 -0600154 }
George Liu0e02c322020-01-01 09:41:51 +0800155 catch (const sdbusplus::exception::SdBusError& e)
Sampa Misra032bd502019-03-06 05:03:22 -0600156 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600157 std::cerr << "Error getting time, PATH=" << hostTimePath
158 << " TIME INTERACE=" << timeInterface << "\n";
Sampa Misra032bd502019-03-06 05:03:22 -0600159
George Liufb8611d2019-12-06 10:14:15 +0800160 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Sampa Misra032bd502019-03-06 05:03:22 -0600161 }
162
Sampa Misra032bd502019-03-06 05:03:22 -0600163 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
164 std::chrono::microseconds(timeUsec))
165 .count();
166
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600167 pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
168 day, month, year);
Sampa Misra032bd502019-03-06 05:03:22 -0600169
George Liufb8611d2019-12-06 10:14:15 +0800170 auto rc = encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS,
171 seconds, minutes, hours, day, month,
172 year, responsePtr);
173 if (rc != PLDM_SUCCESS)
174 {
175 return ccOnlyResponse(request, rc);
176 }
177
vkaverapa6575b82019-04-03 05:33:52 -0500178 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600179}
180
Xiaochao Ma60227a02019-12-04 09:00:12 +0800181Response Handler::setDateTime(const pldm_msg* request, size_t payloadLength)
182{
183 uint8_t seconds = 0;
184 uint8_t minutes = 0;
185 uint8_t hours = 0;
186 uint8_t day = 0;
187 uint8_t month = 0;
188 uint16_t year = 0;
189 std::time_t timeSec;
190
191 constexpr auto setTimeInterface = "xyz.openbmc_project.Time.EpochTime";
192 constexpr auto setTimePath = "/xyz/openbmc_project/time/host";
193 constexpr auto timeSetPro = "Elapsed";
194
195 auto rc = decode_set_date_time_req(request, payloadLength, &seconds,
196 &minutes, &hours, &day, &month, &year);
197 if (rc != PLDM_SUCCESS)
198 {
199 return ccOnlyResponse(request, rc);
200 }
201 timeSec = pldm::responder::utils::timeToEpoch(seconds, minutes, hours, day,
202 month, year);
203 uint64_t timeUsec = std::chrono::duration_cast<std::chrono::microseconds>(
204 std::chrono::seconds(timeSec))
205 .count();
206 std::variant<uint64_t> value{timeUsec};
207 try
208 {
209 pldm::utils::DBusHandler().setDbusProperty(setTimePath, timeSetPro,
210 setTimeInterface, value);
211 }
212 catch (std::exception& e)
213 {
214
215 std::cerr << "Error Setting time,PATH=" << setTimePath
216 << "TIME INTERFACE=" << setTimeInterface
217 << "ERROR=" << e.what() << "\n";
218
219 return ccOnlyResponse(request, PLDM_ERROR);
220 }
221
222 return ccOnlyResponse(request, PLDM_SUCCESS);
223}
224
Sampa Misrab37be312019-07-03 02:26:41 -0500225/** @brief Construct the BIOS string table
226 *
John Wangf719f3b2020-01-17 08:46:22 +0800227 * @param[in,out] biosStringTable - the string table
George Liufb8611d2019-12-06 10:14:15 +0800228 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500229 */
John Wangf719f3b2020-01-17 08:46:22 +0800230Response getBIOSStringTable(BIOSTable& biosStringTable, const pldm_msg* request)
John Wange96e7e52019-10-05 17:47:30 +0800231
Sampa Misrab37be312019-07-03 02:26:41 -0500232{
233 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
234 0);
235 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
John Wangf719f3b2020-01-17 08:46:22 +0800236 if (!biosStringTable.isEmpty())
John Wangdd9a6282019-10-11 18:52:46 +0800237 {
George Liufb8611d2019-12-06 10:14:15 +0800238 auto rc = encode_get_bios_table_resp(
239 request->hdr.instance_id, PLDM_SUCCESS,
240 0, /* next transfer handle */
241 PLDM_START_AND_END, nullptr, response.size(),
242 responsePtr); // filling up the header here
243 if (rc != PLDM_SUCCESS)
244 {
245 return CmdHandler::ccOnlyResponse(request, rc);
246 }
247
John Wangf719f3b2020-01-17 08:46:22 +0800248 biosStringTable.load(response);
John Wangdd9a6282019-10-11 18:52:46 +0800249 return response;
250 }
251 auto biosStrings = bios_parser::getStrings();
252 std::sort(biosStrings.begin(), biosStrings.end());
253 // remove all duplicate strings received from bios json
254 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
255 biosStrings.end());
256
257 size_t sizeWithoutPad = std::accumulate(
258 biosStrings.begin(), biosStrings.end(), 0,
259 [](size_t sum, const std::string& elem) {
260 return sum +
261 pldm_bios_table_string_entry_encode_length(elem.length());
262 });
263
264 Table stringTable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600265 stringTable.reserve(
266 pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
John Wangdd9a6282019-10-11 18:52:46 +0800267
268 stringTable.resize(sizeWithoutPad);
269 auto tablePtr = stringTable.data();
270 for (const auto& elem : biosStrings)
271 {
272 auto entry_length =
273 pldm_bios_table_string_entry_encode_length(elem.length());
274 pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
275 elem.c_str(), elem.length());
276 tablePtr += entry_length;
277 sizeWithoutPad -= entry_length;
Sampa Misrab37be312019-07-03 02:26:41 -0500278 }
279
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600280 pldm::responder::utils::padAndChecksum(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +0800281 biosStringTable.store(stringTable);
John Wangdd9a6282019-10-11 18:52:46 +0800282 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
283 stringTable.size(),
284 0);
285 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800286 auto rc = encode_get_bios_table_resp(
287 request->hdr.instance_id, PLDM_SUCCESS, 0 /* nxtTransferHandle */,
288 PLDM_START_AND_END, stringTable.data(), response.size(), responsePtr);
289 if (rc != PLDM_SUCCESS)
290 {
291 return CmdHandler::ccOnlyResponse(request, rc);
292 }
293
Sampa Misrab37be312019-07-03 02:26:41 -0500294 return response;
295}
296
297/** @brief Find the string handle from the BIOS string table given the name
298 *
299 * @param[in] name - name of the BIOS string
John Wangf719f3b2020-01-17 08:46:22 +0800300 * @param[in] biosStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500301 * @return - uint16_t - handle of the string
302 */
303StringHandle findStringHandle(const std::string& name,
John Wangf719f3b2020-01-17 08:46:22 +0800304 const BIOSTable& biosStringTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500305{
John Wangdd9a6282019-10-11 18:52:46 +0800306 Table table;
John Wangf719f3b2020-01-17 08:46:22 +0800307 biosStringTable.load(table);
John Wangdd9a6282019-10-11 18:52:46 +0800308 auto stringEntry = pldm_bios_table_string_find_by_string(
309 table.data(), table.size(), name.c_str());
310 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500311 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600312 std::cerr << "Reached end of BIOS string table,did not find the "
313 << "handle for the string, STRING=" << name.c_str() << "\n";
314 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500315 }
John Wangdd9a6282019-10-11 18:52:46 +0800316
317 return pldm_bios_table_string_entry_decode_handle(stringEntry);
Sampa Misrab37be312019-07-03 02:26:41 -0500318}
319
320/** @brief Find the string name from the BIOS string table for a string handle
321 *
322 * @param[in] stringHdl - string handle
John Wangf719f3b2020-01-17 08:46:22 +0800323 * @param[in] biosStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500324 *
325 * @return - std::string - name of the corresponding BIOS string
326 */
327std::string findStringName(StringHandle stringHdl,
John Wangf719f3b2020-01-17 08:46:22 +0800328 const BIOSTable& biosStringTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500329{
John Wangdd9a6282019-10-11 18:52:46 +0800330 Table table;
John Wangf719f3b2020-01-17 08:46:22 +0800331 biosStringTable.load(table);
John Wangdd9a6282019-10-11 18:52:46 +0800332 auto stringEntry = pldm_bios_table_string_find_by_handle(
333 table.data(), table.size(), stringHdl);
John Wangdd9a6282019-10-11 18:52:46 +0800334 if (stringEntry == nullptr)
Sampa Misrab37be312019-07-03 02:26:41 -0500335 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600336 std::cerr << "Reached end of BIOS string table,did not find "
337 << "string name for handle, STRING_HANDLE=" << stringHdl
338 << "\n";
John Wang88a349c2020-01-20 14:19:49 +0800339 throw InternalFailure();
Sampa Misrab37be312019-07-03 02:26:41 -0500340 }
John Wangdd9a6282019-10-11 18:52:46 +0800341 auto strLength =
342 pldm_bios_table_string_entry_decode_string_length(stringEntry);
John Wang88a349c2020-01-20 14:19:49 +0800343 std::vector<char> buffer(strLength + 1);
344 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
345 buffer.size());
346
347 return std::string(buffer.data(), buffer.data() + strLength);
Sampa Misrab37be312019-07-03 02:26:41 -0500348}
349
350namespace bios_type_enum
351{
352
Carol Wangdc220c82019-08-26 13:31:31 +0800353using namespace bios_parser::bios_enum;
354
Sampa Misrab37be312019-07-03 02:26:41 -0500355/** @brief Find the indices into the array of the possible values of string
356 * handles for the current values.This is used in attribute value table
357 *
358 * @param[in] possiVals - vector of string handles comprising all the possible
359 * values for an attribute
360 * @param[in] currVals - vector of strings comprising all current values
361 * for an attribute
John Wangf719f3b2020-01-17 08:46:22 +0800362 * @param[in] biosStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500363 *
364 * @return - std::vector<uint8_t> - indices into the array of the possible
365 * values of string handles
366 */
367std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
368 CurrentValues currVals,
John Wangf719f3b2020-01-17 08:46:22 +0800369 const BIOSTable& biosStringTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500370{
371 std::vector<uint8_t> stringIndices;
372
373 for (const auto& currVal : currVals)
374 {
375 StringHandle curHdl;
376 try
377 {
John Wangf719f3b2020-01-17 08:46:22 +0800378 curHdl = findStringHandle(currVal, biosStringTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500379 }
380 catch (InternalFailure& e)
381 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600382 std::cerr << "Exception fetching handle for the string, STRING="
383 << currVal.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500384 continue;
385 }
386
387 uint8_t i = 0;
388 for (auto possiHdl : possiVals)
389 {
390 if (possiHdl == curHdl)
391 {
392 stringIndices.push_back(i);
393 break;
394 }
395 i++;
396 }
397 }
398 return stringIndices;
399}
400
401/** @brief Find the indices into the array of the possible values of string
402 * handles for the default values. This is used in attribute table
403 *
404 * @param[in] possiVals - vector of strings comprising all the possible values
405 * for an attribute
406 * @param[in] defVals - vector of strings comprising all the default values
407 * for an attribute
408 * @return - std::vector<uint8_t> - indices into the array of the possible
409 * values of string
410 */
411std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
412 const DefaultValues& defVals)
413{
414 std::vector<uint8_t> defHdls;
415 for (const auto& defs : defVals)
416 {
417 auto index = std::lower_bound(possiVals.begin(), possiVals.end(), defs);
418 if (index != possiVals.end())
419 {
420 defHdls.push_back(index - possiVals.begin());
421 }
422 }
423
424 return defHdls;
425}
426
427/** @brief Construct the attibute table for BIOS type Enumeration and
428 * Enumeration ReadOnly
John Wangf719f3b2020-01-17 08:46:22 +0800429 * @param[in] biosStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500430 * @param[in] biosJsonDir - path where the BIOS json files are present
Carol Wangdc220c82019-08-26 13:31:31 +0800431 * @param[in,out] attributeTable - the attribute table
Sampa Misrab37be312019-07-03 02:26:41 -0500432 *
Sampa Misrab37be312019-07-03 02:26:41 -0500433 */
John Wangf719f3b2020-01-17 08:46:22 +0800434void constructAttrTable(const BIOSTable& biosStringTable, Table& attributeTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500435{
Sampa Misrab37be312019-07-03 02:26:41 -0500436 const auto& attributeMap = getValues();
Sampa Misrab37be312019-07-03 02:26:41 -0500437 StringHandle strHandle;
438
439 for (const auto& [key, value] : attributeMap)
440 {
441 try
442 {
John Wangf719f3b2020-01-17 08:46:22 +0800443 strHandle = findStringHandle(key, biosStringTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500444 }
445 catch (InternalFailure& e)
446 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600447 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
448 << key.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500449 continue;
450 }
John Wangccc04552019-10-14 14:28:25 +0800451 bool readOnly = (std::get<0>(value));
Sampa Misrab37be312019-07-03 02:26:41 -0500452 PossibleValues possiVals = std::get<1>(value);
453 DefaultValues defVals = std::get<2>(value);
454 // both the possible and default values are stored in sorted manner to
455 // ease in fetching back/comparison
456 std::sort(possiVals.begin(), possiVals.end());
457 std::sort(defVals.begin(), defVals.end());
458
459 std::vector<StringHandle> possiValsByHdl;
460 for (const auto& elem : possiVals)
461 {
462 try
463 {
John Wangf719f3b2020-01-17 08:46:22 +0800464 auto hdl = findStringHandle(elem, biosStringTable);
Sampa Misrab37be312019-07-03 02:26:41 -0500465 possiValsByHdl.push_back(std::move(hdl));
466 }
467 catch (InternalFailure& e)
468 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600469 std::cerr << "Could not find handle for BIOS string, STRING="
470 << elem.c_str() << "\n";
Sampa Misrab37be312019-07-03 02:26:41 -0500471 continue;
472 }
473 }
474 auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
John Wangccc04552019-10-14 14:28:25 +0800475 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
476 possiValsByHdl.size(), defValsByHdl.size());
Sampa Misrab37be312019-07-03 02:26:41 -0500477
John Wangccc04552019-10-14 14:28:25 +0800478 auto attrTableSize = attributeTable.size();
479 attributeTable.resize(attrTableSize + entryLength, 0);
480 struct pldm_bios_table_attr_entry_enum_info info = {
481 strHandle,
482 readOnly,
483 (uint8_t)possiValsByHdl.size(),
484 possiValsByHdl.data(),
485 (uint8_t)defValsByHdl.size(),
486 defValsByHdl.data(),
487 };
488 pldm_bios_table_attr_entry_enum_encode(
489 attributeTable.data() + attrTableSize, entryLength, &info);
Sampa Misrab37be312019-07-03 02:26:41 -0500490 }
Sampa Misrab37be312019-07-03 02:26:41 -0500491}
492
John Wang3ad21752019-10-06 16:42:21 +0800493void constructAttrValueEntry(
494 const struct pldm_bios_attr_table_entry* attrTableEntry,
John Wangf719f3b2020-01-17 08:46:22 +0800495 const std::string& attrName, const BIOSTable& biosStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800496 Table& attrValueTable)
Sampa Misrab37be312019-07-03 02:26:41 -0500497{
John Wang3ad21752019-10-06 16:42:21 +0800498 CurrentValues currVals;
499 try
Sampa Misrab37be312019-07-03 02:26:41 -0500500 {
John Wang3ad21752019-10-06 16:42:21 +0800501 currVals = getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500502 }
John Wang3ad21752019-10-06 16:42:21 +0800503 catch (const std::exception& e)
504 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600505 std::cerr << "getAttrValue returned error for attribute, NAME="
506 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800507 return;
508 }
509 uint8_t pv_num =
510 pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
511 PossibleValuesByHandle pvHdls(pv_num, 0);
512 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
513 pvHdls.data(), pv_num);
514 std::sort(currVals.begin(), currVals.end());
515
John Wangf719f3b2020-01-17 08:46:22 +0800516 auto currValStrIndices = findStrIndices(pvHdls, currVals, biosStringTable);
John Wang3ad21752019-10-06 16:42:21 +0800517
518 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
519 currValStrIndices.size());
520 auto tableSize = attrValueTable.size();
521 attrValueTable.resize(tableSize + entryLength);
522 pldm_bios_table_attr_value_entry_encode_enum(
523 attrValueTable.data() + tableSize, entryLength,
524 attrTableEntry->attr_handle, attrTableEntry->attr_type,
525 currValStrIndices.size(), currValStrIndices.data());
Sampa Misrab37be312019-07-03 02:26:41 -0500526}
527
528} // end namespace bios_type_enum
529
Carol Wangdc220c82019-08-26 13:31:31 +0800530namespace bios_type_string
531{
Carol Wang612f35b2019-08-26 17:14:26 +0800532
533using namespace bios_parser::bios_string;
534
Carol Wangdc220c82019-08-26 13:31:31 +0800535/** @brief Construct the attibute table for BIOS type String and
536 * String ReadOnly
John Wangf719f3b2020-01-17 08:46:22 +0800537 * @param[in] biosStringTable - the string table
Carol Wangdc220c82019-08-26 13:31:31 +0800538 * @param[in] biosJsonDir - path where the BIOS json files are present
539 * @param[in,out] attributeTable - the attribute table
540 *
541 */
John Wangf719f3b2020-01-17 08:46:22 +0800542void constructAttrTable(const BIOSTable& biosStringTable, Table& attributeTable)
Carol Wangdc220c82019-08-26 13:31:31 +0800543{
Carol Wang612f35b2019-08-26 17:14:26 +0800544 const auto& attributeMap = getValues();
545 StringHandle strHandle;
Carol Wang612f35b2019-08-26 17:14:26 +0800546 for (const auto& [key, value] : attributeMap)
547 {
548 try
549 {
John Wangf719f3b2020-01-17 08:46:22 +0800550 strHandle = findStringHandle(key, biosStringTable);
Carol Wang612f35b2019-08-26 17:14:26 +0800551 }
552 catch (InternalFailure& e)
553 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600554 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
555 << key.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +0800556 continue;
557 }
558
John Wangccc04552019-10-14 14:28:25 +0800559 const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
Carol Wang612f35b2019-08-26 17:14:26 +0800560 defaultStr] = value;
John Wangccc04552019-10-14 14:28:25 +0800561 auto entryLength =
562 pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
Carol Wang612f35b2019-08-26 17:14:26 +0800563
John Wangccc04552019-10-14 14:28:25 +0800564 struct pldm_bios_table_attr_entry_string_info info = {
565 strHandle, readOnly, strType, minStrLen,
566 maxStrLen, defaultStrLen, defaultStr.data(),
567 };
568 auto attrTableSize = attributeTable.size();
569 attributeTable.resize(attrTableSize + entryLength, 0);
570 pldm_bios_table_attr_entry_string_encode(
571 attributeTable.data() + attrTableSize, entryLength, &info);
Carol Wang612f35b2019-08-26 17:14:26 +0800572 }
Carol Wangdc220c82019-08-26 13:31:31 +0800573}
Carol Wangb503f9e2019-09-02 16:34:10 +0800574
John Wang3ad21752019-10-06 16:42:21 +0800575void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
576 const std::string& attrName,
John Wangf719f3b2020-01-17 08:46:22 +0800577 const BIOSTable& biosStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800578 Table& attrValueTable)
Carol Wangb503f9e2019-09-02 16:34:10 +0800579{
John Wangf719f3b2020-01-17 08:46:22 +0800580 std::ignore = biosStringTable;
John Wang3ad21752019-10-06 16:42:21 +0800581 std::string currStr;
582 uint16_t currStrLen = 0;
583 try
Carol Wangb503f9e2019-09-02 16:34:10 +0800584 {
John Wang3ad21752019-10-06 16:42:21 +0800585 currStr = getAttrValue(attrName);
586 currStrLen = currStr.size();
Carol Wangb503f9e2019-09-02 16:34:10 +0800587 }
John Wang3ad21752019-10-06 16:42:21 +0800588 catch (const std::exception& e)
589 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600590 std::cerr << "getAttrValue returned error for attribute, NAME="
591 << attrName.c_str() << " ERROR=" << e.what() << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800592 return;
593 }
594 auto entryLength =
595 pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
596 auto tableSize = attrValueTable.size();
597 attrValueTable.resize(tableSize + entryLength);
598 pldm_bios_table_attr_value_entry_encode_string(
599 attrValueTable.data() + tableSize, entryLength,
600 attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
601 currStr.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800602}
603
Carol Wangdc220c82019-08-26 13:31:31 +0800604} // end namespace bios_type_string
605
John Wangdbbc9ff2019-10-25 13:53:46 +0800606namespace bios_type_integer
607{
608
609using namespace bios_parser::bios_integer;
610
611/** @brief Construct the attibute table for BIOS type Integer and
612 * Integer ReadOnly
John Wangf719f3b2020-01-17 08:46:22 +0800613 * @param[in] biosStringTable - the string table
John Wangdbbc9ff2019-10-25 13:53:46 +0800614 * @param[in,out] attributeTable - the attribute table
615 *
616 */
John Wangf719f3b2020-01-17 08:46:22 +0800617void constructAttrTable(const BIOSTable& biosStringTable, Table& attributeTable)
John Wangdbbc9ff2019-10-25 13:53:46 +0800618{
619 const auto& attributeMap = getValues();
620 StringHandle strHandle;
621 for (const auto& [key, value] : attributeMap)
622 {
623 try
624 {
John Wangf719f3b2020-01-17 08:46:22 +0800625 strHandle = findStringHandle(key, biosStringTable);
John Wangdbbc9ff2019-10-25 13:53:46 +0800626 }
627 catch (InternalFailure& e)
628 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600629 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
630 << key.c_str() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800631 continue;
632 }
633
634 const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
635 defaultValue] = value;
636 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
637
638 struct pldm_bios_table_attr_entry_integer_info info = {
639 strHandle, readOnly, lowerBound,
640 upperBound, scalarIncrement, defaultValue,
641 };
642 auto attrTableSize = attributeTable.size();
643 attributeTable.resize(attrTableSize + entryLength, 0);
644 pldm_bios_table_attr_entry_integer_encode(
645 attributeTable.data() + attrTableSize, entryLength, &info);
646 }
647}
648
649void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
650 const std::string& attrName,
John Wangf719f3b2020-01-17 08:46:22 +0800651 const BIOSTable& biosStringTable,
John Wangdbbc9ff2019-10-25 13:53:46 +0800652 Table& attrValueTable)
653{
John Wangf719f3b2020-01-17 08:46:22 +0800654 std::ignore = biosStringTable;
John Wangdbbc9ff2019-10-25 13:53:46 +0800655 uint64_t currentValue;
656 try
657 {
658 currentValue = getAttrValue(attrName);
659 }
660 catch (const std::exception& e)
661 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600662 std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
663 << " ERROR=" << e.what() << "\n";
John Wangdbbc9ff2019-10-25 13:53:46 +0800664 return;
665 }
666 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
667 auto tableSize = attrValueTable.size();
668 attrValueTable.resize(tableSize + entryLength);
669 pldm_bios_table_attr_value_entry_encode_integer(
670 attrValueTable.data() + tableSize, entryLength,
671 attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
672}
673
674} // namespace bios_type_integer
675
John Wang02700402019-10-06 16:34:29 +0800676void traverseBIOSAttrTable(const Table& biosAttrTable,
677 AttrTableEntryHandler handler)
678{
679 std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
680 iter(pldm_bios_table_iter_create(biosAttrTable.data(),
681 biosAttrTable.size(),
682 PLDM_BIOS_ATTR_TABLE),
683 pldm_bios_table_iter_free);
684 while (!pldm_bios_table_iter_is_end(iter.get()))
685 {
686 auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
687 try
688 {
689 handler(table_entry);
690 }
691 catch (const std::exception& e)
692 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600693 std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
694 << e.what() << "\n";
John Wang02700402019-10-06 16:34:29 +0800695 }
696 pldm_bios_table_iter_next(iter.get());
697 }
698}
699
John Wangf719f3b2020-01-17 08:46:22 +0800700using typeHandler = std::function<void(const BIOSTable& biosStringTable,
John Wange96e7e52019-10-05 17:47:30 +0800701 Table& attributeTable)>;
Carol Wangdc220c82019-08-26 13:31:31 +0800702std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
703 {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
John Wangdbbc9ff2019-10-25 13:53:46 +0800704 {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
705 {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
706};
Carol Wangdc220c82019-08-26 13:31:31 +0800707
Sampa Misrab37be312019-07-03 02:26:41 -0500708/** @brief Construct the BIOS attribute table
709 *
John Wangf719f3b2020-01-17 08:46:22 +0800710 * @param[in,out] biosAttributeTable - the attribute table
711 * @param[in] biosStringTable - the string table
Sampa Misrab37be312019-07-03 02:26:41 -0500712 * @param[in] biosJsonDir - path where the BIOS json files are present
George Liufb8611d2019-12-06 10:14:15 +0800713 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500714 */
John Wangf719f3b2020-01-17 08:46:22 +0800715Response getBIOSAttributeTable(BIOSTable& biosAttributeTable,
716 const BIOSTable& biosStringTable,
George Liufb8611d2019-12-06 10:14:15 +0800717 const char* biosJsonDir, const pldm_msg* request)
Sampa Misrab37be312019-07-03 02:26:41 -0500718{
719 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
720 0);
721 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
722 uint32_t nxtTransferHandle = 0;
723 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500724
John Wangf719f3b2020-01-17 08:46:22 +0800725 if (biosAttributeTable.isEmpty())
Sampa Misrab37be312019-07-03 02:26:41 -0500726 { // no persisted table, constructing fresh table and response
Carol Wangdc220c82019-08-26 13:31:31 +0800727 Table attributeTable;
728 fs::path dir(biosJsonDir);
729
730 for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
731 it++)
732 {
733 fs::path file = dir / it->first;
734 if (fs::exists(file))
735 {
John Wangf719f3b2020-01-17 08:46:22 +0800736 it->second(biosStringTable, attributeTable);
Carol Wangdc220c82019-08-26 13:31:31 +0800737 }
738 }
739
740 if (attributeTable.empty())
741 { // no available json file is found
George Liufb8611d2019-12-06 10:14:15 +0800742 return CmdHandler::ccOnlyResponse(request,
743 PLDM_BIOS_TABLE_UNAVAILABLE);
Carol Wangdc220c82019-08-26 13:31:31 +0800744 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600745 pldm::responder::utils::padAndChecksum(attributeTable);
John Wangf719f3b2020-01-17 08:46:22 +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());
George Liufb8611d2019-12-06 10:14:15 +0800751
752 auto rc = encode_get_bios_table_resp(
753 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
754 transferFlag, attributeTable.data(), response.size(), responsePtr);
755 if (rc != PLDM_SUCCESS)
756 {
757 return CmdHandler::ccOnlyResponse(request, rc);
758 }
Sampa Misrab37be312019-07-03 02:26:41 -0500759 }
760 else
761 { // persisted table present, constructing response
George Liufb8611d2019-12-06 10:14:15 +0800762 auto rc = encode_get_bios_table_resp(
763 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
764 transferFlag, nullptr, response.size(),
765 responsePtr); // filling up the header here
766 if (rc != PLDM_SUCCESS)
767 {
768 return CmdHandler::ccOnlyResponse(request, rc);
769 }
John Wangf719f3b2020-01-17 08:46:22 +0800770 biosAttributeTable.load(response);
Sampa Misrab37be312019-07-03 02:26:41 -0500771 }
772
773 return response;
774}
775
John Wang3ad21752019-10-06 16:42:21 +0800776using AttrValTableEntryConstructHandler =
777 std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
778 const std::string& attrName,
John Wangf719f3b2020-01-17 08:46:22 +0800779 const BIOSTable& biosStringTable, Table& table)>;
John Wang3ad21752019-10-06 16:42:21 +0800780
781using AttrType = uint8_t;
782const std::map<AttrType, AttrValTableEntryConstructHandler>
783 AttrValTableConstructMap{
784 {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
785 {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
786 {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
787 {PLDM_BIOS_ENUMERATION_READ_ONLY,
788 bios_type_enum::constructAttrValueEntry},
John Wangdbbc9ff2019-10-25 13:53:46 +0800789 {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
790 {PLDM_BIOS_INTEGER_READ_ONLY,
791 bios_type_integer::constructAttrValueEntry},
John Wang3ad21752019-10-06 16:42:21 +0800792 };
793
794void constructAttrValueTableEntry(
795 const struct pldm_bios_attr_table_entry* attrEntry,
John Wangf719f3b2020-01-17 08:46:22 +0800796 const BIOSTable& biosStringTable, Table& attributeValueTable)
John Wang3ad21752019-10-06 16:42:21 +0800797{
John Wangf719f3b2020-01-17 08:46:22 +0800798 auto attrName = findStringName(attrEntry->string_handle, biosStringTable);
John Wang3ad21752019-10-06 16:42:21 +0800799 if (attrName.empty())
800 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600801 std::cerr << "invalid string handle, STRING_HANDLE="
802 << attrEntry->string_handle << "\n";
John Wang3ad21752019-10-06 16:42:21 +0800803 return;
804 }
805
806 AttrValTableConstructMap.at(attrEntry->attr_type)(
John Wangf719f3b2020-01-17 08:46:22 +0800807 attrEntry, attrName, biosStringTable, attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800808}
809
Sampa Misrab37be312019-07-03 02:26:41 -0500810/** @brief Construct the BIOS attribute value table
811 *
John Wangf719f3b2020-01-17 08:46:22 +0800812 * @param[in,out] biosAttributeValueTable - the attribute value table
813 * @param[in] biosAttributeTable - the attribute table
814 * @param[in] biosStringTable - the string table
George Liufb8611d2019-12-06 10:14:15 +0800815 * @param[in] request - Request message
Sampa Misrab37be312019-07-03 02:26:41 -0500816 */
John Wangf719f3b2020-01-17 08:46:22 +0800817Response getBIOSAttributeValueTable(BIOSTable& biosAttributeValueTable,
818 const BIOSTable& biosAttributeTable,
819 const BIOSTable& biosStringTable,
George Liufb8611d2019-12-06 10:14:15 +0800820 const pldm_msg* request)
Sampa Misrab37be312019-07-03 02:26:41 -0500821{
822 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
823 0);
824 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
825 uint32_t nxtTransferHandle = 0;
826 uint8_t transferFlag = PLDM_START_AND_END;
Sampa Misrab37be312019-07-03 02:26:41 -0500827
John Wangf719f3b2020-01-17 08:46:22 +0800828 if (!biosAttributeValueTable.isEmpty())
John Wang3ad21752019-10-06 16:42:21 +0800829 {
George Liufb8611d2019-12-06 10:14:15 +0800830 auto rc = encode_get_bios_table_resp(
831 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
832 transferFlag, nullptr, response.size(),
833 responsePtr); // filling up the header here
834 if (rc != PLDM_SUCCESS)
835 {
836 return CmdHandler::ccOnlyResponse(request, rc);
837 }
838
John Wangf719f3b2020-01-17 08:46:22 +0800839 biosAttributeValueTable.load(response);
John Wang3ad21752019-10-06 16:42:21 +0800840 return response;
Sampa Misrab37be312019-07-03 02:26:41 -0500841 }
842
John Wang3ad21752019-10-06 16:42:21 +0800843 Table attributeValueTable;
844 Table attributeTable;
John Wangf719f3b2020-01-17 08:46:22 +0800845 biosAttributeTable.load(attributeTable);
John Wang3ad21752019-10-06 16:42:21 +0800846 traverseBIOSAttrTable(
847 attributeTable,
John Wangf719f3b2020-01-17 08:46:22 +0800848 [&biosStringTable, &attributeValueTable](
John Wang3ad21752019-10-06 16:42:21 +0800849 const struct pldm_bios_attr_table_entry* tableEntry) {
John Wangf719f3b2020-01-17 08:46:22 +0800850 constructAttrValueTableEntry(tableEntry, biosStringTable,
John Wang3ad21752019-10-06 16:42:21 +0800851 attributeValueTable);
852 });
853 if (attributeValueTable.empty())
854 {
George Liufb8611d2019-12-06 10:14:15 +0800855 return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
John Wang3ad21752019-10-06 16:42:21 +0800856 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600857 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wangf719f3b2020-01-17 08:46:22 +0800858 biosAttributeValueTable.store(attributeValueTable);
John Wang3ad21752019-10-06 16:42:21 +0800859
860 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
861 attributeValueTable.size());
862 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800863 auto rc = encode_get_bios_table_resp(
864 request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle, transferFlag,
865 attributeValueTable.data(), response.size(), responsePtr);
866 if (rc != PLDM_SUCCESS)
867 {
868 return CmdHandler::ccOnlyResponse(request, rc);
869 }
John Wang3ad21752019-10-06 16:42:21 +0800870
Sampa Misrab37be312019-07-03 02:26:41 -0500871 return response;
872}
873
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600874Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
Sampa Misrab37be312019-07-03 02:26:41 -0500875{
Deepak Kodihallic3d20892019-08-01 05:38:31 -0500876 fs::create_directory(BIOS_TABLES_DIR);
Sampa Misrab37be312019-07-03 02:26:41 -0500877 auto response = internal::buildBIOSTables(request, payloadLength,
878 BIOS_JSONS_DIR, BIOS_TABLES_DIR);
879
880 return response;
881}
882
John Wang8721ed62019-12-05 14:44:43 +0800883Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
884 size_t payloadLength)
885{
886 uint32_t transferHandle;
887 uint8_t transferOpFlag;
888 uint16_t attributeHandle;
889
890 auto rc = decode_get_bios_attribute_current_value_by_handle_req(
891 request, payloadLength, &transferHandle, &transferOpFlag,
892 &attributeHandle);
893 if (rc != PLDM_SUCCESS)
894 {
895 return ccOnlyResponse(request, rc);
896 }
897
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600898 fs::path tablesPath(BIOS_TABLES_DIR);
899 auto stringTablePath = tablesPath / stringTableFile;
John Wangf719f3b2020-01-17 08:46:22 +0800900 BIOSTable biosStringTable(stringTablePath.c_str());
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600901 auto attrTablePath = tablesPath / attrTableFile;
John Wangf719f3b2020-01-17 08:46:22 +0800902 BIOSTable biosAttributeTable(attrTablePath.c_str());
903 if (biosAttributeTable.isEmpty() || biosStringTable.isEmpty())
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600904 {
905 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
906 }
907
908 auto attrValueTablePath = tablesPath / attrValTableFile;
John Wangf719f3b2020-01-17 08:46:22 +0800909 BIOSTable biosAttributeValueTable(attrValueTablePath.c_str());
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600910
John Wangf719f3b2020-01-17 08:46:22 +0800911 if (biosAttributeValueTable.isEmpty())
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600912 {
913 Table attributeValueTable;
914 Table attributeTable;
John Wangf719f3b2020-01-17 08:46:22 +0800915 biosAttributeTable.load(attributeTable);
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600916 traverseBIOSAttrTable(
917 attributeTable,
John Wangf719f3b2020-01-17 08:46:22 +0800918 [&biosStringTable, &attributeValueTable](
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600919 const struct pldm_bios_attr_table_entry* tableEntry) {
John Wangf719f3b2020-01-17 08:46:22 +0800920 constructAttrValueTableEntry(tableEntry, biosStringTable,
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600921 attributeValueTable);
922 });
923 if (attributeValueTable.empty())
924 {
925 return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
926 }
927 pldm::responder::utils::padAndChecksum(attributeValueTable);
John Wangf719f3b2020-01-17 08:46:22 +0800928 biosAttributeValueTable.store(attributeValueTable);
Deepak Kodihalli4976a682020-01-07 05:48:29 -0600929 }
John Wang8721ed62019-12-05 14:44:43 +0800930
931 Response table;
John Wangf719f3b2020-01-17 08:46:22 +0800932 biosAttributeValueTable.load(table);
John Wang8721ed62019-12-05 14:44:43 +0800933
934 auto entry = pldm_bios_table_attr_value_find_by_handle(
935 table.data(), table.size(), attributeHandle);
936 if (entry == nullptr)
937 {
938 return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
939 }
940
John Wang8e877e02020-02-03 16:06:55 +0800941 auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
John Wang8721ed62019-12-05 14:44:43 +0800942 Response response(sizeof(pldm_msg_hdr) +
943 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
John Wang8e877e02020-02-03 16:06:55 +0800944 entryLength,
John Wang8721ed62019-12-05 14:44:43 +0800945 0);
946 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800947 rc = encode_get_bios_current_value_by_handle_resp(
John Wang8e877e02020-02-03 16:06:55 +0800948 request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END,
949 reinterpret_cast<const uint8_t*>(entry), entryLength, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800950 if (rc != PLDM_SUCCESS)
951 {
952 return ccOnlyResponse(request, rc);
953 }
John Wang8721ed62019-12-05 14:44:43 +0800954
955 return response;
956}
957
Sampa Misrab37be312019-07-03 02:26:41 -0500958namespace internal
959{
960
961Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
962 const char* biosJsonDir, const char* biosTablePath)
963{
964 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
965 0);
Sampa Misrab37be312019-07-03 02:26:41 -0500966
John Wange96e7e52019-10-05 17:47:30 +0800967 if (setupConfig(biosJsonDir) != 0)
968 {
George Liufb8611d2019-12-06 10:14:15 +0800969 return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
John Wange96e7e52019-10-05 17:47:30 +0800970 }
971
Sampa Misrab37be312019-07-03 02:26:41 -0500972 uint32_t transferHandle{};
973 uint8_t transferOpFlag{};
974 uint8_t tableType{};
975
976 auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
977 &transferOpFlag, &tableType);
George Liufb8611d2019-12-06 10:14:15 +0800978 if (rc != PLDM_SUCCESS)
Sampa Misrab37be312019-07-03 02:26:41 -0500979 {
George Liufb8611d2019-12-06 10:14:15 +0800980 return CmdHandler::ccOnlyResponse(request, rc);
981 }
Sampa Misrab37be312019-07-03 02:26:41 -0500982
John Wangf719f3b2020-01-17 08:46:22 +0800983 BIOSTable biosStringTable(
George Liufb8611d2019-12-06 10:14:15 +0800984 (std::string(biosTablePath) + "/" + stringTableFile).c_str());
John Wangf719f3b2020-01-17 08:46:22 +0800985 BIOSTable biosAttributeTable(
George Liufb8611d2019-12-06 10:14:15 +0800986 (std::string(biosTablePath) + "/" + attrTableFile).c_str());
John Wangf719f3b2020-01-17 08:46:22 +0800987 BIOSTable biosAttributeValueTable(
George Liufb8611d2019-12-06 10:14:15 +0800988 (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
989 switch (tableType)
990 {
991 case PLDM_BIOS_STRING_TABLE:
Sampa Misrab37be312019-07-03 02:26:41 -0500992
John Wangf719f3b2020-01-17 08:46:22 +0800993 response = getBIOSStringTable(biosStringTable, request);
George Liufb8611d2019-12-06 10:14:15 +0800994 break;
995 case PLDM_BIOS_ATTR_TABLE:
996
John Wangf719f3b2020-01-17 08:46:22 +0800997 if (biosStringTable.isEmpty())
George Liufb8611d2019-12-06 10:14:15 +0800998 {
999 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
1000 }
1001 else
1002 {
1003 response = getBIOSAttributeTable(
John Wangf719f3b2020-01-17 08:46:22 +08001004 biosAttributeTable, biosStringTable, biosJsonDir, request);
George Liufb8611d2019-12-06 10:14:15 +08001005 }
1006 break;
1007 case PLDM_BIOS_ATTR_VAL_TABLE:
John Wangf719f3b2020-01-17 08:46:22 +08001008 if (biosAttributeTable.isEmpty() || biosStringTable.isEmpty())
George Liufb8611d2019-12-06 10:14:15 +08001009 {
1010 rc = PLDM_BIOS_TABLE_UNAVAILABLE;
1011 }
1012 else
1013 {
John Wangf719f3b2020-01-17 08:46:22 +08001014 response = getBIOSAttributeValueTable(biosAttributeValueTable,
1015 biosAttributeTable,
1016 biosStringTable, request);
George Liufb8611d2019-12-06 10:14:15 +08001017 }
1018 break;
1019 default:
1020 rc = PLDM_INVALID_BIOS_TABLE_TYPE;
1021 break;
Sampa Misrab37be312019-07-03 02:26:41 -05001022 }
1023
1024 if (rc != PLDM_SUCCESS)
1025 {
George Liufb8611d2019-12-06 10:14:15 +08001026 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misrab37be312019-07-03 02:26:41 -05001027 }
1028
1029 return response;
1030}
1031
John Wangf719f3b2020-01-17 08:46:22 +08001032} // namespace internal
Sampa Misrab37be312019-07-03 02:26:41 -05001033
John Wangf719f3b2020-01-17 08:46:22 +08001034} // namespace bios
Sampa Misra032bd502019-03-06 05:03:22 -06001035} // namespace responder
1036} // namespace pldm