blob: 67dfb0ec32909ff19bd90d40b0626d22dd572b99 [file] [log] [blame]
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05301#include "bios_table.hpp"
2
3#include <fstream>
4
John Wangf719f3b2020-01-17 08:46:22 +08005#include "bios_table.h"
6
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05307namespace pldm
8{
9
10namespace responder
11{
12
13namespace bios
14{
15
16BIOSTable::BIOSTable(const char* filePath) : filePath(filePath)
17{
18}
19
20bool BIOSTable::isEmpty() const noexcept
21{
22 bool empty = false;
23 try
24 {
25 empty = fs::is_empty(filePath);
26 }
27 catch (fs::filesystem_error& e)
28 {
29 return true;
30 }
31 return empty;
32}
33
34void BIOSTable::store(const Table& table)
35{
36 std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
37 stream.write(reinterpret_cast<const char*>(table.data()), table.size());
38}
39
40void BIOSTable::load(Response& response) const
41{
42 auto currSize = response.size();
43 auto fileSize = fs::file_size(filePath);
44 response.resize(currSize + fileSize);
45 std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
46 stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
47}
48
John Wange297b9f2020-02-03 10:18:13 +080049BIOSStringTable::BIOSStringTable(const Table& stringTable) :
50 stringTable(stringTable)
John Wangf719f3b2020-01-17 08:46:22 +080051{
John Wange297b9f2020-02-03 10:18:13 +080052}
53
54BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
55{
56 biosTable.load(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +080057}
58
59std::string BIOSStringTable::findString(uint16_t handle) const
60{
61 auto stringEntry = pldm_bios_table_string_find_by_handle(
62 stringTable.data(), stringTable.size(), handle);
63 if (stringEntry == nullptr)
64 {
65 throw std::invalid_argument("Invalid String Handle");
66 }
John Wang29683b52020-02-27 16:41:44 +080067 return table::string::decodeString(stringEntry);
John Wangf719f3b2020-01-17 08:46:22 +080068}
69
John Wange297b9f2020-02-03 10:18:13 +080070uint16_t BIOSStringTable::findHandle(const std::string& name) const
71{
72 auto stringEntry = pldm_bios_table_string_find_by_string(
73 stringTable.data(), stringTable.size(), name.c_str());
74 if (stringEntry == nullptr)
75 {
76 throw std::invalid_argument("Invalid String Name");
77 }
78
John Wang29683b52020-02-27 16:41:44 +080079 return table::string::decodeHandle(stringEntry);
John Wange2efdcc2020-02-12 17:02:06 +080080}
81
John Wang29683b52020-02-27 16:41:44 +080082namespace table
83{
84
John Wangd9659342020-02-27 16:46:05 +080085void appendPadAndChecksum(Table& table)
86{
87 auto sizeWithoutPad = table.size();
88 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
89 table.resize(table.size() + padAndChecksumSize);
90
91 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
92 sizeWithoutPad);
93}
94
John Wang29683b52020-02-27 16:41:44 +080095namespace string
96{
97
98uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080099{
100 return pldm_bios_table_string_entry_decode_handle(entry);
101}
102
John Wang29683b52020-02-27 16:41:44 +0800103std::string decodeString(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +0800104{
105 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
106 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
107 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
108 buffer.size());
109 return std::string(buffer.data(), buffer.data() + strLength);
John Wange297b9f2020-02-03 10:18:13 +0800110}
John Wangd9659342020-02-27 16:46:05 +0800111const pldm_bios_string_table_entry* constructEntry(Table& table,
112 const std::string& str)
113{
114 auto tableSize = table.size();
115 auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
116 table.resize(tableSize + entryLength);
117 pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
118 str.c_str(), str.length());
119 return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
120 tableSize);
121}
John Wange297b9f2020-02-03 10:18:13 +0800122
John Wang29683b52020-02-27 16:41:44 +0800123} // namespace string
124
125namespace attribute
126{
127
128TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
129{
130 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
131 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
132 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
133 return {attrHandle, attrType, stringHandle};
134}
135
John Wangd9659342020-02-27 16:46:05 +0800136const pldm_bios_attr_table_entry* findByHandle(const Table& table,
137 uint16_t handle)
138{
139 return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
140 handle);
141}
142
John Wang29683b52020-02-27 16:41:44 +0800143const pldm_bios_attr_table_entry*
144 constructStringEntry(Table& table,
145 pldm_bios_table_attr_entry_string_info* info)
146{
147 auto entryLength =
148 pldm_bios_table_attr_entry_string_encode_length(info->def_length);
149
150 auto tableSize = table.size();
151 table.resize(tableSize + entryLength, 0);
152 pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
153 entryLength, info);
154 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
155 tableSize);
156}
157
John Wang95e6b3c2020-02-13 09:43:24 +0800158const pldm_bios_attr_table_entry*
159 constructIntegerEntry(Table& table,
160 pldm_bios_table_attr_entry_integer_info* info)
161{
162 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
163 auto tableSize = table.size();
164 table.resize(tableSize + entryLength, 0);
165 pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
166 entryLength, info);
167 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
168 tableSize);
169}
170
John Wang29683b52020-02-27 16:41:44 +0800171StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
172{
173 auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
174 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
175 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
176 auto defLength =
177 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
178
179 std::vector<char> buffer(defLength + 1);
180 pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
181 buffer.size());
182 return {strType, minLength, maxLength, defLength,
183 std::string(buffer.data(), buffer.data() + defLength)};
184}
185
John Wang95e6b3c2020-02-13 09:43:24 +0800186IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
187{
188 uint64_t lower, upper, def;
189 uint32_t scalar;
190
191 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
192 &def);
193 return {lower, upper, scalar, def};
194}
195
John Wang29683b52020-02-27 16:41:44 +0800196} // namespace attribute
197
198namespace attribute_value
199{
200
201TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
202{
203 auto handle =
204 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
205 auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
206 return {handle, type};
207}
208
209std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
210{
211 variable_field currentString{};
212 pldm_bios_table_attr_value_entry_string_decode_string(entry,
213 &currentString);
214 return std::string(currentString.ptr,
215 currentString.ptr + currentString.length);
216}
217
John Wang95e6b3c2020-02-13 09:43:24 +0800218uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
219{
220 return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
221}
222
John Wang29683b52020-02-27 16:41:44 +0800223const pldm_bios_attr_val_table_entry*
224 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
225 const std::string& str)
226{
227 auto strLen = str.size();
228 auto entryLength =
229 pldm_bios_table_attr_value_entry_encode_string_length(strLen);
230 auto tableSize = table.size();
231 table.resize(tableSize + entryLength);
232 pldm_bios_table_attr_value_entry_encode_string(
233 table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
234 str.c_str());
235 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
236 tableSize);
237}
John Wang95e6b3c2020-02-13 09:43:24 +0800238
239const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
240 uint16_t attrHandle,
241 uint8_t attrType,
242 uint64_t value)
243{
244 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
245
246 auto tableSize = table.size();
247 table.resize(tableSize + entryLength);
248 pldm_bios_table_attr_value_entry_encode_integer(
249 table.data() + tableSize, entryLength, attrHandle, attrType, value);
250 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
251 tableSize);
252}
253
John Wangd9659342020-02-27 16:46:05 +0800254std::optional<Table> updateTable(const Table& table, const void* entry,
255 size_t size)
256{
257 // Replace the old attribute with the new attribute, the size of table will
258 // change:
259 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
260 // sizeof(oldAttribute) + pad(4-byte alignment, max =
261 // 3)
262 // For simplicity, we use
263 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
264 size_t destBufferLength = table.size() + size + 3;
265 Table destTable(destBufferLength);
266
267 auto rc = pldm_bios_table_attr_value_copy_and_update(
268 table.data(), table.size(), destTable.data(), &destBufferLength, entry,
269 size);
270 if (rc != PLDM_SUCCESS)
271 {
272 return std::nullopt;
273 }
274 destTable.resize(destBufferLength);
275
276 return destTable;
277}
John Wang29683b52020-02-27 16:41:44 +0800278
279} // namespace attribute_value
280
281} // namespace table
282
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +0530283} // namespace bios
284} // namespace responder
285} // namespace pldm