xref: /openbmc/pldm/libpldmresponder/bios_config.hpp (revision 1244acfd5d2bdeeb0262f9efa17bed8dfb38531d)
1d965934fSJohn Wang #pragma once
2d965934fSJohn Wang 
36492f524SGeorge Liu #include "bios_table.h"
46492f524SGeorge Liu 
5d965934fSJohn Wang #include "bios_attribute.hpp"
6d965934fSJohn Wang #include "bios_table.hpp"
7d965934fSJohn Wang 
86492f524SGeorge Liu #include <nlohmann/json.hpp>
96492f524SGeorge Liu 
10d965934fSJohn Wang #include <functional>
11d965934fSJohn Wang #include <iostream>
12d965934fSJohn Wang #include <memory>
13d965934fSJohn Wang #include <optional>
14d965934fSJohn Wang #include <set>
15d965934fSJohn Wang #include <string>
16d965934fSJohn Wang #include <vector>
17d965934fSJohn Wang 
18d965934fSJohn Wang namespace pldm
19d965934fSJohn Wang {
20d965934fSJohn Wang namespace responder
21d965934fSJohn Wang {
22d965934fSJohn Wang namespace bios
23d965934fSJohn Wang {
24d965934fSJohn Wang 
251b180d8aSGeorge Liu enum class BoundType
261b180d8aSGeorge Liu {
271b180d8aSGeorge Liu     LowerBound,
281b180d8aSGeorge Liu     UpperBound,
291b180d8aSGeorge Liu     ScalarIncrement,
301b180d8aSGeorge Liu     MinStringLength,
311b180d8aSGeorge Liu     MaxStringLength,
321b180d8aSGeorge Liu     OneOf
331b180d8aSGeorge Liu };
341b180d8aSGeorge Liu 
351b180d8aSGeorge Liu using AttributeName = std::string;
361b180d8aSGeorge Liu using AttributeType = std::string;
371b180d8aSGeorge Liu using ReadonlyStatus = bool;
381b180d8aSGeorge Liu using DisplayName = std::string;
391b180d8aSGeorge Liu using Description = std::string;
401b180d8aSGeorge Liu using MenuPath = std::string;
411b180d8aSGeorge Liu using CurrentValue = std::variant<int64_t, std::string>;
421b180d8aSGeorge Liu using DefaultValue = std::variant<int64_t, std::string>;
431b180d8aSGeorge Liu using OptionString = std::string;
441b180d8aSGeorge Liu using OptionValue = std::variant<int64_t, std::string>;
451b180d8aSGeorge Liu using Option = std::vector<std::tuple<OptionString, OptionValue>>;
461b180d8aSGeorge Liu using BIOSTableObj =
471b180d8aSGeorge Liu     std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
481b180d8aSGeorge Liu                MenuPath, CurrentValue, DefaultValue, Option>;
491b180d8aSGeorge Liu using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;
501b180d8aSGeorge Liu 
51*1244acfdSGeorge Liu using PendingObj = std::tuple<AttributeType, CurrentValue>;
52*1244acfdSGeorge Liu using PendingAttributes = std::map<AttributeName, PendingObj>;
53*1244acfdSGeorge Liu 
54d965934fSJohn Wang /** @class BIOSConfig
55d965934fSJohn Wang  *  @brief Manager BIOS Attributes
56d965934fSJohn Wang  */
57d965934fSJohn Wang class BIOSConfig
58d965934fSJohn Wang {
59d965934fSJohn Wang   public:
60d965934fSJohn Wang     BIOSConfig() = delete;
61d965934fSJohn Wang     BIOSConfig(const BIOSConfig&) = delete;
62d965934fSJohn Wang     BIOSConfig(BIOSConfig&&) = delete;
63d965934fSJohn Wang     BIOSConfig& operator=(const BIOSConfig&) = delete;
64d965934fSJohn Wang     BIOSConfig& operator=(BIOSConfig&&) = delete;
65d965934fSJohn Wang     ~BIOSConfig() = default;
66d965934fSJohn Wang 
67d965934fSJohn Wang     /** @brief Construct BIOSConfig
68d965934fSJohn Wang      *  @param[in] jsonDir - The directory where json file exists
69d965934fSJohn Wang      *  @param[in] tableDir - The directory where the persistent table is placed
70d965934fSJohn Wang      *  @param[in] dbusHandler - Dbus Handler
71d965934fSJohn Wang      */
72d965934fSJohn Wang     explicit BIOSConfig(const char* jsonDir, const char* tableDir,
73d965934fSJohn Wang                         DBusHandler* const dbusHandler);
74d965934fSJohn Wang 
75d965934fSJohn Wang     /** @brief Set attribute value on dbus and attribute value table
76d965934fSJohn Wang      *  @param[in] entry - attribute value entry
77d965934fSJohn Wang      *  @param[in] size - size of the attribute value entry
78d965934fSJohn Wang      *  @return pldm_completion_codes
79d965934fSJohn Wang      */
80d965934fSJohn Wang     int setAttrValue(const void* entry, size_t size);
81d965934fSJohn Wang 
82d965934fSJohn Wang     /** @brief Remove the persistent tables */
83d965934fSJohn Wang     void removeTables();
84d965934fSJohn Wang 
85d965934fSJohn Wang     /** @brief Build bios tables(string,attribute,attribute value table)*/
86d965934fSJohn Wang     void buildTables();
87d965934fSJohn Wang 
88d965934fSJohn Wang     /** @brief Get BIOS table of specified type
89d965934fSJohn Wang      *  @param[in] tableType - The table type
90d965934fSJohn Wang      *  @return The bios table, std::nullopt if the table is unaviliable
91d965934fSJohn Wang      */
92d965934fSJohn Wang     std::optional<Table> getBIOSTable(pldm_bios_table_types tableType);
93d965934fSJohn Wang 
941b180d8aSGeorge Liu     /** @brief set BIOS table
951b180d8aSGeorge Liu      *  @param[in] tableType - Indicates what table is being transferred
961b180d8aSGeorge Liu      *             {BIOSStringTable=0x0, BIOSAttributeTable=0x1,
971b180d8aSGeorge Liu      *              BIOSAttributeValueTable=0x2}
981b180d8aSGeorge Liu      *  @param[in] table - table data
991b180d8aSGeorge Liu      *  @return pldm_completion_codes
1001b180d8aSGeorge Liu      */
1011b180d8aSGeorge Liu     int setBIOSTable(uint8_t tableType, const Table& table);
1021b180d8aSGeorge Liu 
103d965934fSJohn Wang   private:
104d965934fSJohn Wang     const fs::path jsonDir;
105d965934fSJohn Wang     const fs::path tableDir;
106d965934fSJohn Wang     DBusHandler* const dbusHandler;
1071b180d8aSGeorge Liu     bool isUpdateProperty;
1081b180d8aSGeorge Liu     BaseBIOSTable baseBIOSTableMaps;
109d965934fSJohn Wang 
110d965934fSJohn Wang     // vector persists all attributes
111d965934fSJohn Wang     using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>;
112d965934fSJohn Wang     BIOSAttributes biosAttributes;
113d965934fSJohn Wang 
11446ece063SSampa Misra     using propName = std::string;
11546ece063SSampa Misra     using DbusChObjProperties = std::map<propName, PropertyValue>;
11646ece063SSampa Misra 
11746ece063SSampa Misra     // vector to catch the D-Bus property change signals for BIOS attributes
11846ece063SSampa Misra     std::vector<std::unique_ptr<sdbusplus::bus::match::match>> biosAttrMatch;
11946ece063SSampa Misra 
12046ece063SSampa Misra     /** @brief Method to update a BIOS attribute when the corresponding Dbus
12146ece063SSampa Misra      *  property is changed
12246ece063SSampa Misra      *  @param[in] chProperties - list of properties which have changed
12346ece063SSampa Misra      *  @param[in] biosAttrIndex - Index of BIOSAttribute pointer in
12446ece063SSampa Misra      * biosAttributes
12546ece063SSampa Misra      *  @return - none
12646ece063SSampa Misra      */
12746ece063SSampa Misra     void processBiosAttrChangeNotification(
12846ece063SSampa Misra         const DbusChObjProperties& chProperties, uint32_t biosAttrIndex);
12946ece063SSampa Misra 
130d965934fSJohn Wang     /** @brief Construct an attribute and persist it
131d965934fSJohn Wang      *  @tparam T - attribute type
132d965934fSJohn Wang      *  @param[in] entry - json entry
133d965934fSJohn Wang      */
134d965934fSJohn Wang     template <typename T>
135d965934fSJohn Wang     void constructAttribute(const Json& entry)
136d965934fSJohn Wang     {
137d965934fSJohn Wang         try
138d965934fSJohn Wang         {
139d965934fSJohn Wang             biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler));
14046ece063SSampa Misra             auto biosAttrIndex = biosAttributes.size() - 1;
14146ece063SSampa Misra             auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
14246ece063SSampa Misra 
14346ece063SSampa Misra             if (dBusMap.has_value())
14446ece063SSampa Misra             {
14546ece063SSampa Misra                 using namespace sdbusplus::bus::match::rules;
14646ece063SSampa Misra                 biosAttrMatch.push_back(
14746ece063SSampa Misra                     std::make_unique<sdbusplus::bus::match::match>(
14846ece063SSampa Misra                         pldm::utils::DBusHandler::getBus(),
14946ece063SSampa Misra                         propertiesChanged(dBusMap->objectPath,
15046ece063SSampa Misra                                           dBusMap->interface),
15146ece063SSampa Misra                         [this,
15246ece063SSampa Misra                          biosAttrIndex](sdbusplus::message::message& msg) {
15346ece063SSampa Misra                             DbusChObjProperties props;
15446ece063SSampa Misra                             std::string iface;
15546ece063SSampa Misra                             msg.read(iface, props);
15646ece063SSampa Misra                             processBiosAttrChangeNotification(props,
15746ece063SSampa Misra                                                               biosAttrIndex);
15846ece063SSampa Misra                         }));
15946ece063SSampa Misra             }
160d965934fSJohn Wang         }
161d965934fSJohn Wang         catch (const std::exception& e)
162d965934fSJohn Wang         {
163d965934fSJohn Wang             std::cerr << "Constructs Attribute Error, " << e.what()
164d965934fSJohn Wang                       << std::endl;
165d965934fSJohn Wang         }
166d965934fSJohn Wang     }
167d965934fSJohn Wang 
168d965934fSJohn Wang     /** Construct attributes and persist them */
169d965934fSJohn Wang     void constructAttributes();
170d965934fSJohn Wang 
171d965934fSJohn Wang     using ParseHandler = std::function<void(const Json& entry)>;
172d965934fSJohn Wang 
173d965934fSJohn Wang     /** @brief Helper function to parse json
174d965934fSJohn Wang      *  @param[in] filePath - Path of json file
175d965934fSJohn Wang      *  @param[in] handler - Handler to process each entry in the json
176d965934fSJohn Wang      */
177d965934fSJohn Wang     void load(const fs::path& filePath, ParseHandler handler);
178d965934fSJohn Wang 
179d965934fSJohn Wang     /** @brief Build String Table and persist it
180d965934fSJohn Wang      *  @return The built string table, std::nullopt if it fails.
181d965934fSJohn Wang      */
182d965934fSJohn Wang     std::optional<Table> buildAndStoreStringTable();
183d965934fSJohn Wang 
184d965934fSJohn Wang     /** @brief Build attr table and attr value table and persist them
185d965934fSJohn Wang      *  @param[in] stringTable - The string Table
186d965934fSJohn Wang      */
187d965934fSJohn Wang     void buildAndStoreAttrTables(const Table& stringTable);
188d965934fSJohn Wang 
189d965934fSJohn Wang     /** @brief Persist the table
190d965934fSJohn Wang      *  @param[in] path - Path to persist the table
191d965934fSJohn Wang      *  @param[in] table - The table
192d965934fSJohn Wang      */
193d965934fSJohn Wang     void storeTable(const fs::path& path, const Table& table);
194d965934fSJohn Wang 
195d965934fSJohn Wang     /** @brief Load bios table to ram
196d965934fSJohn Wang      *  @param[in] path - Path of the table
197d965934fSJohn Wang      *  @return The table, std::nullopt if loading fails
198d965934fSJohn Wang      */
199d965934fSJohn Wang     std::optional<Table> loadTable(const fs::path& path);
2008241b340SJohn Wang 
2018241b340SJohn Wang     /** @brief Check the attribute value to update
2028241b340SJohn Wang      *  @param[in] attrValueEntry - The attribute value entry to update
2038241b340SJohn Wang      *  @param[in] attrEntry - The attribute table entry
2048241b340SJohn Wang      *  @param[in] stringTable - The string  table
2058241b340SJohn Wang      *  @return pldm_completion_codes
2068241b340SJohn Wang      */
2078241b340SJohn Wang     int checkAttrValueToUpdate(
2088241b340SJohn Wang         const pldm_bios_attr_val_table_entry* attrValueEntry,
2098241b340SJohn Wang         const pldm_bios_attr_table_entry* attrEntry, Table& stringTable);
2101b180d8aSGeorge Liu 
2111b180d8aSGeorge Liu     /** @brief Check the attribute table
2121b180d8aSGeorge Liu      *  @param[in] table - The table
2131b180d8aSGeorge Liu      *  @return pldm_completion_codes
2141b180d8aSGeorge Liu      */
2151b180d8aSGeorge Liu     int checkAttributeTable(const Table& table);
2161b180d8aSGeorge Liu 
2171b180d8aSGeorge Liu     /** @brief Check the attribute value table
2181b180d8aSGeorge Liu      *  @param[in] table - The table
2191b180d8aSGeorge Liu      *  @return pldm_completion_codes
2201b180d8aSGeorge Liu      */
2211b180d8aSGeorge Liu     int checkAttributeValueTable(const Table& table);
2221b180d8aSGeorge Liu 
2231b180d8aSGeorge Liu     /** @brief Update the BaseBIOSTable property of the D-Bus interface
2241b180d8aSGeorge Liu      */
2251b180d8aSGeorge Liu     void updateBaseBIOSTableProperty();
226*1244acfdSGeorge Liu 
227*1244acfdSGeorge Liu     /** @brief Listen the PendingAttributes property of the D-Bus interface and
228*1244acfdSGeorge Liu      *         update BaseBIOSTable
229*1244acfdSGeorge Liu      */
230*1244acfdSGeorge Liu     void listenPendingAttributes();
231*1244acfdSGeorge Liu 
232*1244acfdSGeorge Liu     /** @brief Find attribute handle from bios attribute table
233*1244acfdSGeorge Liu      *  @param[in] attrName - attribute name
234*1244acfdSGeorge Liu      *  @return attribute handle
235*1244acfdSGeorge Liu      */
236*1244acfdSGeorge Liu     uint16_t findAttrHandle(const std::string& attrName);
237*1244acfdSGeorge Liu 
238*1244acfdSGeorge Liu     /** @brief Listen the PendingAttributes property of the D-Bus interface
239*1244acfdSGeorge Liu      * and update BaseBIOSTable
240*1244acfdSGeorge Liu      *  @param[in] msg - Data associated with subscribed signal
241*1244acfdSGeorge Liu      */
242*1244acfdSGeorge Liu     void constructPendingAttribute(const PendingAttributes& pendingAttributes);
243d965934fSJohn Wang };
244d965934fSJohn Wang 
245d965934fSJohn Wang } // namespace bios
246d965934fSJohn Wang } // namespace responder
247d965934fSJohn Wang } // namespace pldm
248