1 #pragma once 2 3 #include <stdint.h> 4 5 #include <filesystem> 6 #include <optional> 7 #include <string> 8 #include <vector> 9 10 #include "libpldm/bios.h" 11 #include "libpldm/bios_table.h" 12 13 namespace pldm 14 { 15 16 namespace responder 17 { 18 19 namespace bios 20 { 21 22 using Table = std::vector<uint8_t>; 23 using Response = std::vector<uint8_t>; 24 namespace fs = std::filesystem; 25 26 /** @class BIOSTable 27 * 28 * @brief Provides APIs for storing and loading BIOS tables 29 * 30 * Typical usage is as follows: 31 * BIOSTable table(BIOS_STRING_TABLE_FILE_PATH); 32 * if (table.isEmpty()) { // no persisted table 33 * // construct BIOSTable 't' 34 * // prepare Response 'r' 35 * // send response to GetBIOSTable 36 * table.store(t); // persisted 37 * } 38 * else { // persisted table exists 39 * // create Response 'r' which has response fields (except 40 * // the table itself) to a GetBIOSTable command 41 * table.load(r); // actual table will be pushed back to the vector 42 * } 43 */ 44 class BIOSTable 45 { 46 public: 47 /** @brief Ctor - set file path to persist BIOS table 48 * 49 * @param[in] filePath - file where BIOS table should be persisted 50 */ 51 BIOSTable(const char* filePath); 52 53 /** @brief Checks if there's a persisted BIOS table 54 * 55 * @return bool - true if table exists, false otherwise 56 */ 57 bool isEmpty() const noexcept; 58 59 /** @brief Persist a BIOS table(string/attribute/attribute value) 60 * 61 * @param[in] table - BIOS table 62 */ 63 void store(const Table& table); 64 65 /** @brief Load BIOS table from persistent store to memory 66 * 67 * @param[in,out] response - PLDM response message to GetBIOSTable 68 * (excluding table), table will be pushed back to this. 69 */ 70 void load(Response& response) const; 71 72 private: 73 // file storing PLDM BIOS table 74 fs::path filePath; 75 }; 76 77 /** @class BIOSStringTableInterface 78 * @brief Provide interfaces to the BIOS string table operations 79 */ 80 class BIOSStringTableInterface 81 { 82 public: 83 virtual ~BIOSStringTableInterface() = default; 84 85 /** @brief Find the string name from the BIOS string table for a string 86 * handle 87 * @param[in] handle - string handle 88 * @return name of the corresponding BIOS string 89 */ 90 virtual std::string findString(uint16_t handle) const = 0; 91 92 /** @brief Find the string handle from the BIOS string table by the given 93 * name 94 * @param[in] name - name of the BIOS string 95 * @return handle of the string 96 */ 97 virtual uint16_t findHandle(const std::string& name) const = 0; 98 }; 99 100 /** @class BIOSStringTable 101 * @brief Collection of BIOS string table operations. 102 */ 103 class BIOSStringTable : public BIOSStringTableInterface 104 { 105 public: 106 /** @brief Constructs BIOSStringTable 107 * 108 * @param[in] stringTable - The stringTable in RAM 109 */ 110 BIOSStringTable(const Table& stringTable); 111 112 /** @brief Constructs BIOSStringTable 113 * 114 * @param[in] biosTable - The BIOSTable 115 */ 116 BIOSStringTable(const BIOSTable& biosTable); 117 118 /** @brief Find the string name from the BIOS string table for a string 119 * handle 120 * @param[in] handle - string handle 121 * @return name of the corresponding BIOS string 122 * @throw std::invalid_argument if the string can not be found. 123 */ 124 std::string findString(uint16_t handle) const override; 125 126 /** @brief Find the string handle from the BIOS string table by the given 127 * name 128 * @param[in] name - name of the BIOS string 129 * @return handle of the string 130 * @throw std::invalid_argument if the string can not be found 131 */ 132 uint16_t findHandle(const std::string& name) const override; 133 134 private: 135 Table stringTable; 136 }; 137 138 namespace table 139 { 140 141 /** @brief Append Pad and Checksum 142 * 143 * @param[in,out] table - table to be appended with pad and checksum 144 */ 145 void appendPadAndChecksum(Table& table); 146 147 namespace string 148 { 149 150 /** @brief Get the string handle for the entry 151 * @param[in] entry - Pointer to a bios string table entry 152 * @return Handle to identify a string in the bios string table 153 */ 154 uint16_t decodeHandle(const pldm_bios_string_table_entry* entry); 155 156 /** @brief Get the string from the entry 157 * @param[in] entry - Pointer to a bios string table entry 158 * @return The String 159 */ 160 std::string decodeString(const pldm_bios_string_table_entry* entry); 161 162 /** @brief construct entry of string table at the end of the given 163 * table 164 * @param[in,out] table - The given table 165 * @param[in] str - string itself 166 * @return pointer to the constructed entry 167 */ 168 const pldm_bios_string_table_entry* constructEntry(Table& table, 169 const std::string& str); 170 171 } // namespace string 172 173 namespace attribute 174 { 175 176 /** @struct TableHeader 177 * @brief Header of attribute table 178 */ 179 struct TableHeader 180 { 181 uint16_t attrHandle; 182 uint8_t attrType; 183 uint16_t stringHandle; 184 }; 185 186 /** @brief Decode header of attribute table entry 187 * @param[in] entry - Pointer to an attribute table entry 188 * @return Attribute table header 189 */ 190 TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry); 191 192 /** @brief Find attribute entry by handle 193 * @param[in] table - attribute table 194 * @param[in] handle - attribute handle 195 * @return Pointer to the attribute table entry 196 */ 197 const pldm_bios_attr_table_entry* findByHandle(const Table& table, 198 uint16_t handle); 199 200 /** @struct StringField 201 * @brief String field of attribute table 202 */ 203 struct StringField 204 { 205 uint8_t stringType; 206 uint16_t minLength; 207 uint16_t maxLength; 208 uint16_t defLength; 209 std::string defString; 210 }; 211 212 /** @brief decode string entry of attribute table 213 * @param[in] entry - Pointer to an attribute table entry 214 * @return String field of the entry 215 */ 216 StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry); 217 218 /** @brief construct string entry of attribute table at the end of the given 219 * table 220 * @param[in,out] table - The given table 221 * @param[in] info - string info 222 * @return pointer to the constructed entry 223 */ 224 const pldm_bios_attr_table_entry* 225 constructStringEntry(Table& table, 226 pldm_bios_table_attr_entry_string_info* info); 227 228 /** @struct IntegerField 229 * @brief Integer field of attribute table 230 */ 231 struct IntegerField 232 { 233 uint64_t lowerBound; 234 uint64_t upperBound; 235 uint32_t scalarIncrement; 236 uint64_t defaultValue; 237 }; 238 239 /** @brief construct integer entry of attribute table at the end of the 240 * given table 241 * @param[in,out] table - The given table 242 * @param[in] info - integer info 243 * @return pointer to the constructed entry 244 */ 245 const pldm_bios_attr_table_entry* 246 constructIntegerEntry(Table& table, 247 pldm_bios_table_attr_entry_integer_info* info); 248 249 /** @brief decode integer entry of attribute table 250 * @param[in] entry - Pointer to an attribute table entry 251 * @return Integer field of the entry 252 */ 253 IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry); 254 255 /** @struct EnumField 256 * @brief Enum field of attribute table 257 */ 258 struct EnumField 259 { 260 std::vector<uint16_t> possibleValueStringHandle; 261 std::vector<uint8_t> defaultValueIndex; 262 }; 263 264 /** @brief decode enum entry of attribute table 265 * @param[in] entry - Pointer to an attribute table entry 266 * @return Enum field of the entry 267 */ 268 EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry); 269 270 /** @brief construct enum entry of attribute table at the end of the 271 * given table 272 * @param[in,out] table - The given table 273 * @param[in] info - enum info 274 * @return pointer to the constructed entry 275 */ 276 const pldm_bios_attr_table_entry* 277 constructEnumEntry(Table& table, 278 pldm_bios_table_attr_entry_enum_info* info); 279 280 } // namespace attribute 281 282 namespace attribute_value 283 { 284 285 /** @struct TableHeader 286 * @brief Header of attribute value table 287 */ 288 struct TableHeader 289 { 290 uint16_t attrHandle; 291 uint8_t attrType; 292 }; 293 294 /** @brief Decode header of attribute value table 295 * @param[in] entry - Pointer to an attribute value table entry 296 * @return Attribute value table header 297 */ 298 TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry); 299 300 /** @brief Decode string entry of attribute value table 301 * @param[in] entry - Pointer to an attribute value table entry 302 * @return The decoded string 303 */ 304 std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry); 305 306 /** @brief Decode integer entry of attribute value table 307 * @param[in] entry - Pointer to an attribute value table entry 308 * @return The decoded integer 309 */ 310 uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry); 311 312 /** @brief Decode enum entry of attribute value table 313 * @param[in] entry - Pointer to an attribute value table entry 314 * @return Current value string handle indices 315 */ 316 std::vector<uint8_t> 317 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry); 318 319 /** @brief Construct string entry of attribute value table at the end of the 320 * given table 321 * @param[in] table - The given table 322 * @param[in] attrHandle - attribute handle 323 * @param[in] attrType - attribute type 324 * @param[in] str - The string 325 * @return Pointer to the constructed entry 326 */ 327 const pldm_bios_attr_val_table_entry* 328 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType, 329 const std::string& str); 330 331 /** @brief Construct integer entry of attribute value table at the end of 332 * the given table 333 * @param[in] table - The given table 334 * @param[in] attrHandle - attribute handle 335 * @param[in] attrType - attribute type 336 * @param[in] value - The integer 337 * @return Pointer to the constructed entry 338 */ 339 const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table, 340 uint16_t attrHandle, 341 uint8_t attrType, 342 uint64_t value); 343 344 /** @brief Construct enum entry of attribute value table at the end of 345 * the given table 346 * @param[in] table - The given table 347 * @param[in] attrHandle - attribute handle 348 * @param[in] attrType - attribute type 349 * @param[in] handleIndices - handle indices 350 * @return Pointer to the constructed entry 351 */ 352 const pldm_bios_attr_val_table_entry* 353 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType, 354 const std::vector<uint8_t>& handleIndices); 355 356 /** @brief construct a table with an new entry 357 * @param[in] table - the table need to be updated 358 * @param[in] entry - the new attribute value entry 359 * @param[in] size - size of the new entry 360 * @return newly constructed table, std::nullopt if failed 361 */ 362 std::optional<Table> updateTable(const Table& table, const void* entry, 363 size_t size); 364 365 } // namespace attribute_value 366 367 } // namespace table 368 369 } // namespace bios 370 } // namespace responder 371 } // namespace pldm 372