1cb7f2d44SDeepak Kodihalli #include "bios_table.hpp"
2cb7f2d44SDeepak Kodihalli 
3c453e164SGeorge Liu #include <libpldm/base.h>
4c453e164SGeorge Liu #include <libpldm/bios_table.h>
5c453e164SGeorge Liu #include <libpldm/utils.h>
6f719f3bfSJohn Wang 
7488f19d0SAndrew Jeffery #include <phosphor-logging/lg2.hpp>
8488f19d0SAndrew Jeffery 
96492f524SGeorge Liu #include <fstream>
106492f524SGeorge Liu 
11*89644441SRiya Dixit PHOSPHOR_LOG2_USING;
12*89644441SRiya Dixit 
13cb7f2d44SDeepak Kodihalli namespace pldm
14cb7f2d44SDeepak Kodihalli {
15cb7f2d44SDeepak Kodihalli namespace responder
16cb7f2d44SDeepak Kodihalli {
17cb7f2d44SDeepak Kodihalli namespace bios
18cb7f2d44SDeepak Kodihalli {
BIOSTable(const char * filePath)196da4f91bSPatrick Williams BIOSTable::BIOSTable(const char* filePath) : filePath(filePath) {}
20cb7f2d44SDeepak Kodihalli 
isEmpty() const21cb7f2d44SDeepak Kodihalli bool BIOSTable::isEmpty() const noexcept
22cb7f2d44SDeepak Kodihalli {
23cb7f2d44SDeepak Kodihalli     bool empty = false;
24cb7f2d44SDeepak Kodihalli     try
25cb7f2d44SDeepak Kodihalli     {
26cb7f2d44SDeepak Kodihalli         empty = fs::is_empty(filePath);
27cb7f2d44SDeepak Kodihalli     }
2858cbcaf2SKamalkumar Patel     catch (const fs::filesystem_error&)
29cb7f2d44SDeepak Kodihalli     {
30cb7f2d44SDeepak Kodihalli         return true;
31cb7f2d44SDeepak Kodihalli     }
32cb7f2d44SDeepak Kodihalli     return empty;
33cb7f2d44SDeepak Kodihalli }
34cb7f2d44SDeepak Kodihalli 
store(const Table & table)35cb7f2d44SDeepak Kodihalli void BIOSTable::store(const Table& table)
36cb7f2d44SDeepak Kodihalli {
37cb7f2d44SDeepak Kodihalli     std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
38cb7f2d44SDeepak Kodihalli     stream.write(reinterpret_cast<const char*>(table.data()), table.size());
39cb7f2d44SDeepak Kodihalli }
40cb7f2d44SDeepak Kodihalli 
load(Response & response) const41cb7f2d44SDeepak Kodihalli void BIOSTable::load(Response& response) const
42cb7f2d44SDeepak Kodihalli {
43cb7f2d44SDeepak Kodihalli     auto currSize = response.size();
44cb7f2d44SDeepak Kodihalli     auto fileSize = fs::file_size(filePath);
45cb7f2d44SDeepak Kodihalli     response.resize(currSize + fileSize);
46cb7f2d44SDeepak Kodihalli     std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
47cb7f2d44SDeepak Kodihalli     stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
48cb7f2d44SDeepak Kodihalli }
49cb7f2d44SDeepak Kodihalli 
BIOSStringTable(const Table & stringTable)50e297b9f4SJohn Wang BIOSStringTable::BIOSStringTable(const Table& stringTable) :
51e297b9f4SJohn Wang     stringTable(stringTable)
526492f524SGeorge Liu {}
53e297b9f4SJohn Wang 
BIOSStringTable(const BIOSTable & biosTable)54e297b9f4SJohn Wang BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
55e297b9f4SJohn Wang {
56e297b9f4SJohn Wang     biosTable.load(stringTable);
57f719f3bfSJohn Wang }
58f719f3bfSJohn Wang 
findString(uint16_t handle) const59f719f3bfSJohn Wang std::string BIOSStringTable::findString(uint16_t handle) const
60f719f3bfSJohn Wang {
61f719f3bfSJohn Wang     auto stringEntry = pldm_bios_table_string_find_by_handle(
62f719f3bfSJohn Wang         stringTable.data(), stringTable.size(), handle);
63f719f3bfSJohn Wang     if (stringEntry == nullptr)
64f719f3bfSJohn Wang     {
65f719f3bfSJohn Wang         throw std::invalid_argument("Invalid String Handle");
66f719f3bfSJohn Wang     }
6729683b53SJohn Wang     return table::string::decodeString(stringEntry);
68f719f3bfSJohn Wang }
69f719f3bfSJohn Wang 
findHandle(const std::string & name) const70e297b9f4SJohn Wang uint16_t BIOSStringTable::findHandle(const std::string& name) const
71e297b9f4SJohn Wang {
72e297b9f4SJohn Wang     auto stringEntry = pldm_bios_table_string_find_by_string(
73e297b9f4SJohn Wang         stringTable.data(), stringTable.size(), name.c_str());
74e297b9f4SJohn Wang     if (stringEntry == nullptr)
75e297b9f4SJohn Wang     {
76e297b9f4SJohn Wang         throw std::invalid_argument("Invalid String Name");
77e297b9f4SJohn Wang     }
78e297b9f4SJohn Wang 
7929683b53SJohn Wang     return table::string::decodeHandle(stringEntry);
80e2efdcceSJohn Wang }
81e2efdcceSJohn Wang 
8229683b53SJohn Wang namespace table
8329683b53SJohn Wang {
appendPadAndChecksum(Table & table)84d965934fSJohn Wang void appendPadAndChecksum(Table& table)
85d965934fSJohn Wang {
86c43f2115SAndrew Jeffery     size_t payloadSize = table.size();
87c43f2115SAndrew Jeffery     table.resize(payloadSize + pldm_bios_table_pad_checksum_size(payloadSize));
88c43f2115SAndrew Jeffery     // No validation of return value as preconditions are satisfied
89c43f2115SAndrew Jeffery     pldm_bios_table_append_pad_checksum_check(table.data(), table.size(),
90c43f2115SAndrew Jeffery                                               &payloadSize);
91d965934fSJohn Wang }
92d965934fSJohn Wang 
9329683b53SJohn Wang namespace string
9429683b53SJohn Wang {
decodeHandle(const pldm_bios_string_table_entry * entry)9529683b53SJohn Wang uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
96e2efdcceSJohn Wang {
97e2efdcceSJohn Wang     return pldm_bios_table_string_entry_decode_handle(entry);
98e2efdcceSJohn Wang }
99e2efdcceSJohn Wang 
decodeString(const pldm_bios_string_table_entry * entry)10029683b53SJohn Wang std::string decodeString(const pldm_bios_string_table_entry* entry)
101e2efdcceSJohn Wang {
102e2efdcceSJohn Wang     auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
103e2efdcceSJohn Wang     std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
104488f19d0SAndrew Jeffery     // Preconditions are upheld therefore no error check necessary
105488f19d0SAndrew Jeffery     pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
106e2efdcceSJohn Wang                                                      buffer.size());
107e2efdcceSJohn Wang     return std::string(buffer.data(), buffer.data() + strLength);
108e297b9f4SJohn Wang }
constructEntry(Table & table,const std::string & str)109d965934fSJohn Wang const pldm_bios_string_table_entry* constructEntry(Table& table,
110d965934fSJohn Wang                                                    const std::string& str)
111d965934fSJohn Wang {
112d965934fSJohn Wang     auto tableSize = table.size();
113d965934fSJohn Wang     auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
114d965934fSJohn Wang     table.resize(tableSize + entryLength);
115488f19d0SAndrew Jeffery     // Preconditions are upheld therefore no error check necessary
116488f19d0SAndrew Jeffery     pldm_bios_table_string_entry_encode_check(
117488f19d0SAndrew Jeffery         table.data() + tableSize, entryLength, str.c_str(), str.length());
118d965934fSJohn Wang     return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
119d965934fSJohn Wang                                                            tableSize);
120d965934fSJohn Wang }
121e297b9f4SJohn Wang 
12229683b53SJohn Wang } // namespace string
12329683b53SJohn Wang 
12429683b53SJohn Wang namespace attribute
12529683b53SJohn Wang {
decodeHeader(const pldm_bios_attr_table_entry * entry)12629683b53SJohn Wang TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
12729683b53SJohn Wang {
12829683b53SJohn Wang     auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
12929683b53SJohn Wang     auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
13029683b53SJohn Wang     auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
13129683b53SJohn Wang     return {attrHandle, attrType, stringHandle};
13229683b53SJohn Wang }
13329683b53SJohn Wang 
findByHandle(const Table & table,uint16_t handle)134d965934fSJohn Wang const pldm_bios_attr_table_entry* findByHandle(const Table& table,
135d965934fSJohn Wang                                                uint16_t handle)
136d965934fSJohn Wang {
137d965934fSJohn Wang     return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
138d965934fSJohn Wang                                                handle);
139d965934fSJohn Wang }
140d965934fSJohn Wang 
findByStringHandle(const Table & table,uint16_t handle)14145fed20fSJohn Wang const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
14245fed20fSJohn Wang                                                      uint16_t handle)
14345fed20fSJohn Wang {
14445fed20fSJohn Wang     return pldm_bios_table_attr_find_by_string_handle(table.data(),
14545fed20fSJohn Wang                                                       table.size(), handle);
14645fed20fSJohn Wang }
14745fed20fSJohn Wang 
14829683b53SJohn Wang const pldm_bios_attr_table_entry*
constructStringEntry(Table & table,pldm_bios_table_attr_entry_string_info * info)14929683b53SJohn Wang     constructStringEntry(Table& table,
15029683b53SJohn Wang                          pldm_bios_table_attr_entry_string_info* info)
15129683b53SJohn Wang {
15229683b53SJohn Wang     auto entryLength =
15329683b53SJohn Wang         pldm_bios_table_attr_entry_string_encode_length(info->def_length);
15429683b53SJohn Wang 
15529683b53SJohn Wang     auto tableSize = table.size();
15629683b53SJohn Wang     table.resize(tableSize + entryLength, 0);
157488f19d0SAndrew Jeffery     int rc = pldm_bios_table_attr_entry_string_encode_check(
158488f19d0SAndrew Jeffery         table.data() + tableSize, entryLength, info);
159488f19d0SAndrew Jeffery     if (rc != PLDM_SUCCESS)
160488f19d0SAndrew Jeffery     {
161*89644441SRiya Dixit         error("Failed to encode BIOS table string entry, response code '{RC}'",
162*89644441SRiya Dixit               "RC", rc);
163488f19d0SAndrew Jeffery         throw std::runtime_error("Failed to encode BIOS table string entry");
164488f19d0SAndrew Jeffery     }
16529683b53SJohn Wang     return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
16629683b53SJohn Wang                                                          tableSize);
16729683b53SJohn Wang }
16829683b53SJohn Wang 
16995e6b3c1SJohn Wang const pldm_bios_attr_table_entry*
constructIntegerEntry(Table & table,pldm_bios_table_attr_entry_integer_info * info)17095e6b3c1SJohn Wang     constructIntegerEntry(Table& table,
17195e6b3c1SJohn Wang                           pldm_bios_table_attr_entry_integer_info* info)
17295e6b3c1SJohn Wang {
17395e6b3c1SJohn Wang     auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
17495e6b3c1SJohn Wang     auto tableSize = table.size();
17595e6b3c1SJohn Wang     table.resize(tableSize + entryLength, 0);
176d15ecf92SAndrew Jeffery     int rc = pldm_bios_table_attr_entry_integer_encode_check(
177d15ecf92SAndrew Jeffery         table.data() + tableSize, entryLength, info);
178d15ecf92SAndrew Jeffery     if (rc != PLDM_SUCCESS)
179d15ecf92SAndrew Jeffery     {
180*89644441SRiya Dixit         error(
181*89644441SRiya Dixit             "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
182*89644441SRiya Dixit             "RC", rc);
183d15ecf92SAndrew Jeffery         throw std::runtime_error(
184d15ecf92SAndrew Jeffery             "Failed to encode BIOS attribute table integer entry");
185d15ecf92SAndrew Jeffery     }
18695e6b3c1SJohn Wang     return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
18795e6b3c1SJohn Wang                                                          tableSize);
18895e6b3c1SJohn Wang }
18995e6b3c1SJohn Wang 
decodeStringEntry(const pldm_bios_attr_table_entry * entry)19029683b53SJohn Wang StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
19129683b53SJohn Wang {
19229683b53SJohn Wang     auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
19329683b53SJohn Wang     auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
19429683b53SJohn Wang     auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
195488f19d0SAndrew Jeffery     uint16_t defLength;
196488f19d0SAndrew Jeffery     int rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
197488f19d0SAndrew Jeffery         entry, &defLength);
198488f19d0SAndrew Jeffery     if (rc != PLDM_SUCCESS)
199488f19d0SAndrew Jeffery     {
200*89644441SRiya Dixit         error(
201*89644441SRiya Dixit             "Failed to decode BIOS table string definition length, response code '{RC}'",
202*89644441SRiya Dixit             "RC", rc);
203488f19d0SAndrew Jeffery         throw std::runtime_error(
204488f19d0SAndrew Jeffery             "Failed to decode BIOS table string definitionlength");
205488f19d0SAndrew Jeffery     }
20629683b53SJohn Wang 
20729683b53SJohn Wang     std::vector<char> buffer(defLength + 1);
20829683b53SJohn Wang     pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
20929683b53SJohn Wang                                                         buffer.size());
21029683b53SJohn Wang     return {strType, minLength, maxLength, defLength,
21129683b53SJohn Wang             std::string(buffer.data(), buffer.data() + defLength)};
21229683b53SJohn Wang }
21329683b53SJohn Wang 
decodeIntegerEntry(const pldm_bios_attr_table_entry * entry)21495e6b3c1SJohn Wang IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
21595e6b3c1SJohn Wang {
21695e6b3c1SJohn Wang     uint64_t lower, upper, def;
21795e6b3c1SJohn Wang     uint32_t scalar;
21895e6b3c1SJohn Wang 
21995e6b3c1SJohn Wang     pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
22095e6b3c1SJohn Wang                                               &def);
22195e6b3c1SJohn Wang     return {lower, upper, scalar, def};
22295e6b3c1SJohn Wang }
22395e6b3c1SJohn Wang 
2243be7085eSJohn Wang const pldm_bios_attr_table_entry*
constructEnumEntry(Table & table,pldm_bios_table_attr_entry_enum_info * info)2253be7085eSJohn Wang     constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
2263be7085eSJohn Wang {
2273be7085eSJohn Wang     auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
2283be7085eSJohn Wang         info->pv_num, info->def_num);
2293be7085eSJohn Wang 
2303be7085eSJohn Wang     auto tableSize = table.size();
2313be7085eSJohn Wang     table.resize(tableSize + entryLength, 0);
232488f19d0SAndrew Jeffery     // Preconditions are upheld therefore no error check necessary
233488f19d0SAndrew Jeffery     pldm_bios_table_attr_entry_enum_encode_check(table.data() + tableSize,
2343be7085eSJohn Wang                                                  entryLength, info);
2353be7085eSJohn Wang 
2363be7085eSJohn Wang     return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
2373be7085eSJohn Wang                                                          tableSize);
2383be7085eSJohn Wang }
2393be7085eSJohn Wang 
decodeEnumEntry(const pldm_bios_attr_table_entry * entry)2403be7085eSJohn Wang EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
2413be7085eSJohn Wang {
242488f19d0SAndrew Jeffery     uint8_t pvNum;
243488f19d0SAndrew Jeffery     int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNum);
244488f19d0SAndrew Jeffery     if (rc != PLDM_SUCCESS)
245488f19d0SAndrew Jeffery     {
246*89644441SRiya Dixit         error(
247*89644441SRiya Dixit             "Failed to decode the number of possible values for BIOS table enum entry, response code '{RC}'",
248*89644441SRiya Dixit             "RC", rc);
249488f19d0SAndrew Jeffery         throw std::runtime_error(
250488f19d0SAndrew Jeffery             "Failed to decode the number of possible values for BIOS table enum entry");
251488f19d0SAndrew Jeffery     }
2523be7085eSJohn Wang     std::vector<uint16_t> pvHdls(pvNum, 0);
253488f19d0SAndrew Jeffery     // Preconditions are upheld therefore no error check necessary
254488f19d0SAndrew Jeffery     pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, pvHdls.data(),
255488f19d0SAndrew Jeffery                                                          pvNum);
256488f19d0SAndrew Jeffery     // Preconditions are upheld therefore no error check necessary
257488f19d0SAndrew Jeffery     uint8_t defNum;
258488f19d0SAndrew Jeffery     pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNum);
2593be7085eSJohn Wang     std::vector<uint8_t> defIndices(defNum, 0);
2603be7085eSJohn Wang     pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
2613be7085eSJohn Wang                                                        defIndices.size());
2623be7085eSJohn Wang     return {pvHdls, defIndices};
2633be7085eSJohn Wang }
2643be7085eSJohn Wang 
26529683b53SJohn Wang } // namespace attribute
26629683b53SJohn Wang 
26729683b53SJohn Wang namespace attribute_value
26829683b53SJohn Wang {
decodeHeader(const pldm_bios_attr_val_table_entry * entry)26929683b53SJohn Wang TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
27029683b53SJohn Wang {
27129683b53SJohn Wang     auto handle =
27229683b53SJohn Wang         pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
27329683b53SJohn Wang     auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
27429683b53SJohn Wang     return {handle, type};
27529683b53SJohn Wang }
27629683b53SJohn Wang 
decodeStringEntry(const pldm_bios_attr_val_table_entry * entry)27729683b53SJohn Wang std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
27829683b53SJohn Wang {
27929683b53SJohn Wang     variable_field currentString{};
28029683b53SJohn Wang     pldm_bios_table_attr_value_entry_string_decode_string(entry,
28129683b53SJohn Wang                                                           &currentString);
28229683b53SJohn Wang     return std::string(currentString.ptr,
28329683b53SJohn Wang                        currentString.ptr + currentString.length);
28429683b53SJohn Wang }
28529683b53SJohn Wang 
decodeIntegerEntry(const pldm_bios_attr_val_table_entry * entry)28695e6b3c1SJohn Wang uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
28795e6b3c1SJohn Wang {
28895e6b3c1SJohn Wang     return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
28995e6b3c1SJohn Wang }
29095e6b3c1SJohn Wang 
2913be7085eSJohn Wang std::vector<uint8_t>
decodeEnumEntry(const pldm_bios_attr_val_table_entry * entry)2923be7085eSJohn Wang     decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
2933be7085eSJohn Wang {
2943be7085eSJohn Wang     auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
2953be7085eSJohn Wang     std::vector<uint8_t> currHdls(number, 0);
2963be7085eSJohn Wang     pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
2973be7085eSJohn Wang                                                          currHdls.size());
2983be7085eSJohn Wang     return currHdls;
2993be7085eSJohn Wang }
3003be7085eSJohn Wang 
30129683b53SJohn Wang const pldm_bios_attr_val_table_entry*
constructStringEntry(Table & table,uint16_t attrHandle,uint8_t attrType,const std::string & str)30229683b53SJohn Wang     constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
30329683b53SJohn Wang                          const std::string& str)
30429683b53SJohn Wang {
30529683b53SJohn Wang     auto strLen = str.size();
30629683b53SJohn Wang     auto entryLength =
30729683b53SJohn Wang         pldm_bios_table_attr_value_entry_encode_string_length(strLen);
30829683b53SJohn Wang     auto tableSize = table.size();
30929683b53SJohn Wang     table.resize(tableSize + entryLength);
310d15ecf92SAndrew Jeffery     int rc = pldm_bios_table_attr_value_entry_encode_string_check(
31129683b53SJohn Wang         table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
31229683b53SJohn Wang         str.c_str());
313d15ecf92SAndrew Jeffery     if (rc != PLDM_SUCCESS)
314d15ecf92SAndrew Jeffery     {
315*89644441SRiya Dixit         error(
316*89644441SRiya Dixit             "Failed to encode BIOS attribute table string entry, response code '{RC}'",
317*89644441SRiya Dixit             "RC", rc);
318d15ecf92SAndrew Jeffery         throw std::runtime_error(
319d15ecf92SAndrew Jeffery             "Failed to encode BIOS attribute table string entry");
320d15ecf92SAndrew Jeffery     }
32129683b53SJohn Wang     return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
32229683b53SJohn Wang                                                              tableSize);
32329683b53SJohn Wang }
32495e6b3c1SJohn Wang 
constructIntegerEntry(Table & table,uint16_t attrHandle,uint8_t attrType,uint64_t value)32595e6b3c1SJohn Wang const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
32695e6b3c1SJohn Wang                                                             uint16_t attrHandle,
32795e6b3c1SJohn Wang                                                             uint8_t attrType,
32895e6b3c1SJohn Wang                                                             uint64_t value)
32995e6b3c1SJohn Wang {
33095e6b3c1SJohn Wang     auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
33195e6b3c1SJohn Wang 
33295e6b3c1SJohn Wang     auto tableSize = table.size();
33395e6b3c1SJohn Wang     table.resize(tableSize + entryLength);
334c727fb40SAndrew Jeffery     int rc = pldm_bios_table_attr_value_entry_encode_integer_check(
33595e6b3c1SJohn Wang         table.data() + tableSize, entryLength, attrHandle, attrType, value);
336c727fb40SAndrew Jeffery     if (rc != PLDM_SUCCESS)
337c727fb40SAndrew Jeffery     {
338*89644441SRiya Dixit         error(
339*89644441SRiya Dixit             "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
340*89644441SRiya Dixit             "RC", rc);
341c727fb40SAndrew Jeffery         throw std::runtime_error(
342c727fb40SAndrew Jeffery             "Failed to encode BIOS attribute table integery entry");
343c727fb40SAndrew Jeffery     }
34495e6b3c1SJohn Wang     return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
34595e6b3c1SJohn Wang                                                              tableSize);
34695e6b3c1SJohn Wang }
34795e6b3c1SJohn Wang 
3483be7085eSJohn Wang const pldm_bios_attr_val_table_entry*
constructEnumEntry(Table & table,uint16_t attrHandle,uint8_t attrType,const std::vector<uint8_t> & handleIndices)3493be7085eSJohn Wang     constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
3503be7085eSJohn Wang                        const std::vector<uint8_t>& handleIndices)
3513be7085eSJohn Wang {
3523be7085eSJohn Wang     auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
3533be7085eSJohn Wang         handleIndices.size());
3543be7085eSJohn Wang     auto tableSize = table.size();
3553be7085eSJohn Wang     table.resize(tableSize + entryLength);
356d15ecf92SAndrew Jeffery     int rc = pldm_bios_table_attr_value_entry_encode_enum_check(
3573be7085eSJohn Wang         table.data() + tableSize, entryLength, attrHandle, attrType,
3583be7085eSJohn Wang         handleIndices.size(), handleIndices.data());
359d15ecf92SAndrew Jeffery     if (rc != PLDM_SUCCESS)
360d15ecf92SAndrew Jeffery     {
361*89644441SRiya Dixit         error(
362*89644441SRiya Dixit             "Failed to encode BIOS attribute table enum entry, response code '{RC}'",
363*89644441SRiya Dixit             "RC", rc);
364d15ecf92SAndrew Jeffery         throw std::runtime_error(
365d15ecf92SAndrew Jeffery             "Failed to encode BIOS attribute table enum entry");
366d15ecf92SAndrew Jeffery     }
3673be7085eSJohn Wang     return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
3683be7085eSJohn Wang                                                              tableSize);
3693be7085eSJohn Wang }
3703be7085eSJohn Wang 
updateTable(const Table & table,const void * entry,size_t size)371d965934fSJohn Wang std::optional<Table> updateTable(const Table& table, const void* entry,
372d965934fSJohn Wang                                  size_t size)
373d965934fSJohn Wang {
374d965934fSJohn Wang     // Replace the old attribute with the new attribute, the size of table will
375d965934fSJohn Wang     // change:
376d965934fSJohn Wang     //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
377d965934fSJohn Wang     //                      sizeof(oldAttribute) + pad(4-byte alignment, max =
378d965934fSJohn Wang     //                      3)
379d965934fSJohn Wang     // For simplicity, we use
380d965934fSJohn Wang     //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
381d965934fSJohn Wang     size_t destBufferLength = table.size() + size + 3;
382d965934fSJohn Wang     Table destTable(destBufferLength);
383d965934fSJohn Wang 
384d965934fSJohn Wang     auto rc = pldm_bios_table_attr_value_copy_and_update(
385d965934fSJohn Wang         table.data(), table.size(), destTable.data(), &destBufferLength, entry,
386d965934fSJohn Wang         size);
387d965934fSJohn Wang     if (rc != PLDM_SUCCESS)
388d965934fSJohn Wang     {
389d965934fSJohn Wang         return std::nullopt;
390d965934fSJohn Wang     }
391d965934fSJohn Wang     destTable.resize(destBufferLength);
392d965934fSJohn Wang 
393d965934fSJohn Wang     return destTable;
394d965934fSJohn Wang }
39529683b53SJohn Wang 
39629683b53SJohn Wang } // namespace attribute_value
39729683b53SJohn Wang 
39829683b53SJohn Wang } // namespace table
39929683b53SJohn Wang 
400cb7f2d44SDeepak Kodihalli } // namespace bios
401cb7f2d44SDeepak Kodihalli } // namespace responder
402cb7f2d44SDeepak Kodihalli } // namespace pldm
403