1d965934fSJohn Wang #pragma once 2d965934fSJohn Wang 3d965934fSJohn Wang #include "bios_attribute.hpp" 4d965934fSJohn Wang #include "bios_table.hpp" 57f839f9dSTom Joseph #include "pldmd/dbus_impl_requester.hpp" 6c0c79481SSampa Misra #include "requester/handler.hpp" 7d965934fSJohn Wang 8c453e164SGeorge Liu #include <libpldm/bios_table.h> 9c453e164SGeorge Liu 106492f524SGeorge Liu #include <nlohmann/json.hpp> 116492f524SGeorge Liu 12d965934fSJohn Wang #include <functional> 13d965934fSJohn Wang #include <iostream> 14d965934fSJohn Wang #include <memory> 15d965934fSJohn Wang #include <optional> 16d965934fSJohn Wang #include <set> 17d965934fSJohn Wang #include <string> 18d965934fSJohn Wang #include <vector> 19d965934fSJohn Wang 20d965934fSJohn Wang namespace pldm 21d965934fSJohn Wang { 22d965934fSJohn Wang namespace responder 23d965934fSJohn Wang { 24d965934fSJohn Wang namespace bios 25d965934fSJohn Wang { 261b180d8aSGeorge Liu enum class BoundType 271b180d8aSGeorge Liu { 281b180d8aSGeorge Liu LowerBound, 291b180d8aSGeorge Liu UpperBound, 301b180d8aSGeorge Liu ScalarIncrement, 311b180d8aSGeorge Liu MinStringLength, 321b180d8aSGeorge Liu MaxStringLength, 331b180d8aSGeorge Liu OneOf 341b180d8aSGeorge Liu }; 351b180d8aSGeorge Liu 361b180d8aSGeorge Liu using AttributeName = std::string; 371b180d8aSGeorge Liu using AttributeType = std::string; 381b180d8aSGeorge Liu using ReadonlyStatus = bool; 391b180d8aSGeorge Liu using DisplayName = std::string; 401b180d8aSGeorge Liu using Description = std::string; 411b180d8aSGeorge Liu using MenuPath = std::string; 421b180d8aSGeorge Liu using CurrentValue = std::variant<int64_t, std::string>; 431b180d8aSGeorge Liu using DefaultValue = std::variant<int64_t, std::string>; 441b180d8aSGeorge Liu using OptionString = std::string; 451b180d8aSGeorge Liu using OptionValue = std::variant<int64_t, std::string>; 461b180d8aSGeorge Liu using Option = std::vector<std::tuple<OptionString, OptionValue>>; 471b180d8aSGeorge Liu using BIOSTableObj = 481b180d8aSGeorge Liu std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description, 491b180d8aSGeorge Liu MenuPath, CurrentValue, DefaultValue, Option>; 501b180d8aSGeorge Liu using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>; 511b180d8aSGeorge Liu 521244acfdSGeorge Liu using PendingObj = std::tuple<AttributeType, CurrentValue>; 531244acfdSGeorge Liu using PendingAttributes = std::map<AttributeName, PendingObj>; 541244acfdSGeorge Liu 55d965934fSJohn Wang /** @class BIOSConfig 56d965934fSJohn Wang * @brief Manager BIOS Attributes 57d965934fSJohn Wang */ 58d965934fSJohn Wang class BIOSConfig 59d965934fSJohn Wang { 60d965934fSJohn Wang public: 61d965934fSJohn Wang BIOSConfig() = delete; 62d965934fSJohn Wang BIOSConfig(const BIOSConfig&) = delete; 63d965934fSJohn Wang BIOSConfig(BIOSConfig&&) = delete; 64d965934fSJohn Wang BIOSConfig& operator=(const BIOSConfig&) = delete; 65d965934fSJohn Wang BIOSConfig& operator=(BIOSConfig&&) = delete; 66d965934fSJohn Wang ~BIOSConfig() = default; 67d965934fSJohn Wang 68d965934fSJohn Wang /** @brief Construct BIOSConfig 69d965934fSJohn Wang * @param[in] jsonDir - The directory where json file exists 70d965934fSJohn Wang * @param[in] tableDir - The directory where the persistent table is placed 71d965934fSJohn Wang * @param[in] dbusHandler - Dbus Handler 727f839f9dSTom Joseph * @param[in] fd - socket descriptor to communicate to host 737f839f9dSTom Joseph * @param[in] eid - MCTP EID of host firmware 747f839f9dSTom Joseph * @param[in] requester - pointer to Requester object 75c0c79481SSampa Misra * @param[in] handler - PLDM request handler 76d965934fSJohn Wang */ 77c0c79481SSampa Misra explicit BIOSConfig( 78c0c79481SSampa Misra const char* jsonDir, const char* tableDir, 795079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid, 80c0c79481SSampa Misra dbus_api::Requester* requester, 81c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler); 82d965934fSJohn Wang 83d965934fSJohn Wang /** @brief Set attribute value on dbus and attribute value table 84d965934fSJohn Wang * @param[in] entry - attribute value entry 85d965934fSJohn Wang * @param[in] size - size of the attribute value entry 86cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 876d6d1e8dSGeorge Liu * @param[in] updateDBus - update Attr value D-Bus property 886d6d1e8dSGeorge Liu * if this is set to true 897f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 907f839f9dSTom Joseph * if this is set to true 91d965934fSJohn Wang * @return pldm_completion_codes 92d965934fSJohn Wang */ 93cac0ebb2SSagar Srinivas int setAttrValue(const void* entry, size_t size, bool isBMC, 94cac0ebb2SSagar Srinivas bool updateDBus = true, bool updateBaseBIOSTable = true); 95d965934fSJohn Wang 96d965934fSJohn Wang /** @brief Remove the persistent tables */ 97d965934fSJohn Wang void removeTables(); 98d965934fSJohn Wang 99d965934fSJohn Wang /** @brief Build bios tables(string,attribute,attribute value table)*/ 100d965934fSJohn Wang void buildTables(); 101d965934fSJohn Wang 102d965934fSJohn Wang /** @brief Get BIOS table of specified type 103d965934fSJohn Wang * @param[in] tableType - The table type 104d965934fSJohn Wang * @return The bios table, std::nullopt if the table is unaviliable 105d965934fSJohn Wang */ 106d965934fSJohn Wang std::optional<Table> getBIOSTable(pldm_bios_table_types tableType); 107d965934fSJohn Wang 1081b180d8aSGeorge Liu /** @brief set BIOS table 1091b180d8aSGeorge Liu * @param[in] tableType - Indicates what table is being transferred 1101b180d8aSGeorge Liu * {BIOSStringTable=0x0, BIOSAttributeTable=0x1, 1111b180d8aSGeorge Liu * BIOSAttributeValueTable=0x2} 1121b180d8aSGeorge Liu * @param[in] table - table data 1137f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 1147f839f9dSTom Joseph * if this is set to true 1151b180d8aSGeorge Liu * @return pldm_completion_codes 1161b180d8aSGeorge Liu */ 1177f839f9dSTom Joseph int setBIOSTable(uint8_t tableType, const Table& table, 1187f839f9dSTom Joseph bool updateBaseBIOSTable = true); 1191b180d8aSGeorge Liu 120d965934fSJohn Wang private: 121ca7b2524STom Joseph /** @enum Index into the fields in the BaseBIOSTable 122ca7b2524STom Joseph */ 123ca7b2524STom Joseph enum class Index : uint8_t 124ca7b2524STom Joseph { 125ca7b2524STom Joseph attributeType = 0, 126ca7b2524STom Joseph readOnly, 127ca7b2524STom Joseph displayName, 128ca7b2524STom Joseph description, 129ca7b2524STom Joseph menuPath, 130ca7b2524STom Joseph currentValue, 131ca7b2524STom Joseph defaultValue, 132ca7b2524STom Joseph options, 133ca7b2524STom Joseph }; 134ca7b2524STom Joseph 135d965934fSJohn Wang const fs::path jsonDir; 136d965934fSJohn Wang const fs::path tableDir; 1375079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler; 1381b180d8aSGeorge Liu BaseBIOSTable baseBIOSTableMaps; 139d965934fSJohn Wang 1407f839f9dSTom Joseph /** @brief socket descriptor to communicate to host */ 1417f839f9dSTom Joseph int fd; 1427f839f9dSTom Joseph 1437f839f9dSTom Joseph /** @brief MCTP EID of host firmware */ 1447f839f9dSTom Joseph uint8_t eid; 1457f839f9dSTom Joseph 1467f839f9dSTom Joseph /** @brief pointer to Requester object, primarily used to access API to 1477f839f9dSTom Joseph * obtain PLDM instance id. 1487f839f9dSTom Joseph */ 1497f839f9dSTom Joseph dbus_api::Requester* requester; 1507f839f9dSTom Joseph 151c0c79481SSampa Misra /** @brief PLDM request handler */ 152c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler; 153c0c79481SSampa Misra 154d965934fSJohn Wang // vector persists all attributes 155d965934fSJohn Wang using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>; 156d965934fSJohn Wang BIOSAttributes biosAttributes; 157d965934fSJohn Wang 15846ece063SSampa Misra using propName = std::string; 1595079ac4aSBrad Bishop using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>; 16046ece063SSampa Misra 161d987c94cSMatt Spinler using ifaceName = std::string; 162d987c94cSMatt Spinler using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>; 163d987c94cSMatt Spinler 16446ece063SSampa Misra // vector to catch the D-Bus property change signals for BIOS attributes 16584b790cbSPatrick Williams std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch; 16646ece063SSampa Misra 16746ece063SSampa Misra /** @brief Method to update a BIOS attribute when the corresponding Dbus 16846ece063SSampa Misra * property is changed 16946ece063SSampa Misra * @param[in] chProperties - list of properties which have changed 17046ece063SSampa Misra * @param[in] biosAttrIndex - Index of BIOSAttribute pointer in 17146ece063SSampa Misra * biosAttributes 17246ece063SSampa Misra * @return - none 17346ece063SSampa Misra */ 17446ece063SSampa Misra void processBiosAttrChangeNotification( 17546ece063SSampa Misra const DbusChObjProperties& chProperties, uint32_t biosAttrIndex); 17646ece063SSampa Misra 177d965934fSJohn Wang /** @brief Construct an attribute and persist it 178d965934fSJohn Wang * @tparam T - attribute type 179d965934fSJohn Wang * @param[in] entry - json entry 180d965934fSJohn Wang */ 181d965934fSJohn Wang template <typename T> 182d965934fSJohn Wang void constructAttribute(const Json& entry) 183d965934fSJohn Wang { 184d965934fSJohn Wang try 185d965934fSJohn Wang { 186d965934fSJohn Wang biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler)); 18746ece063SSampa Misra auto biosAttrIndex = biosAttributes.size() - 1; 18846ece063SSampa Misra auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap(); 18946ece063SSampa Misra 19046ece063SSampa Misra if (dBusMap.has_value()) 19146ece063SSampa Misra { 19246ece063SSampa Misra using namespace sdbusplus::bus::match::rules; 19346ece063SSampa Misra biosAttrMatch.push_back( 19484b790cbSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 19546ece063SSampa Misra pldm::utils::DBusHandler::getBus(), 19646ece063SSampa Misra propertiesChanged(dBusMap->objectPath, 19746ece063SSampa Misra dBusMap->interface), 19884b790cbSPatrick Williams [this, biosAttrIndex](sdbusplus::message_t& msg) { 19946ece063SSampa Misra DbusChObjProperties props; 20046ece063SSampa Misra std::string iface; 20146ece063SSampa Misra msg.read(iface, props); 20246ece063SSampa Misra processBiosAttrChangeNotification(props, 20346ece063SSampa Misra biosAttrIndex); 20446ece063SSampa Misra })); 205d987c94cSMatt Spinler 206d987c94cSMatt Spinler biosAttrMatch.push_back( 207*b90fb7fdSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 208d987c94cSMatt Spinler pldm::utils::DBusHandler::getBus(), 209d987c94cSMatt Spinler interfacesAdded() + argNpath(0, dBusMap->objectPath), 210d987c94cSMatt Spinler [this, biosAttrIndex, interface = dBusMap->interface]( 211*b90fb7fdSPatrick Williams sdbusplus::message_t& msg) { 212d987c94cSMatt Spinler sdbusplus::message::object_path path; 213d987c94cSMatt Spinler DbusIfacesAdded interfaces; 214d987c94cSMatt Spinler 215d987c94cSMatt Spinler msg.read(path, interfaces); 216d987c94cSMatt Spinler auto ifaceIt = interfaces.find(interface); 217d987c94cSMatt Spinler if (ifaceIt != interfaces.end()) 218d987c94cSMatt Spinler { 219d987c94cSMatt Spinler processBiosAttrChangeNotification( 220d987c94cSMatt Spinler ifaceIt->second, biosAttrIndex); 221d987c94cSMatt Spinler } 222d987c94cSMatt Spinler })); 22346ece063SSampa Misra } 224d965934fSJohn Wang } 225d965934fSJohn Wang catch (const std::exception& e) 226d965934fSJohn Wang { 227d965934fSJohn Wang std::cerr << "Constructs Attribute Error, " << e.what() 228d965934fSJohn Wang << std::endl; 229d965934fSJohn Wang } 230d965934fSJohn Wang } 231d965934fSJohn Wang 232d965934fSJohn Wang /** Construct attributes and persist them */ 233d965934fSJohn Wang void constructAttributes(); 234d965934fSJohn Wang 235d965934fSJohn Wang using ParseHandler = std::function<void(const Json& entry)>; 236d965934fSJohn Wang 237d965934fSJohn Wang /** @brief Helper function to parse json 238d965934fSJohn Wang * @param[in] filePath - Path of json file 239d965934fSJohn Wang * @param[in] handler - Handler to process each entry in the json 240d965934fSJohn Wang */ 241d965934fSJohn Wang void load(const fs::path& filePath, ParseHandler handler); 242d965934fSJohn Wang 243d965934fSJohn Wang /** @brief Build String Table and persist it 244d965934fSJohn Wang * @return The built string table, std::nullopt if it fails. 245d965934fSJohn Wang */ 246d965934fSJohn Wang std::optional<Table> buildAndStoreStringTable(); 247d965934fSJohn Wang 248ca7b2524STom Joseph /** @brief Build attribute table and attribute value table and persist them 249ca7b2524STom Joseph * Read the BaseBIOSTable from the bios-settings-manager and update 250ca7b2524STom Joseph * attribute table and attribute value table. 251ca7b2524STom Joseph * 252d965934fSJohn Wang * @param[in] stringTable - The string Table 253d965934fSJohn Wang */ 254d965934fSJohn Wang void buildAndStoreAttrTables(const Table& stringTable); 255d965934fSJohn Wang 256d965934fSJohn Wang /** @brief Persist the table 257d965934fSJohn Wang * @param[in] path - Path to persist the table 258d965934fSJohn Wang * @param[in] table - The table 259d965934fSJohn Wang */ 260d965934fSJohn Wang void storeTable(const fs::path& path, const Table& table); 261d965934fSJohn Wang 262d965934fSJohn Wang /** @brief Load bios table to ram 263d965934fSJohn Wang * @param[in] path - Path of the table 264d965934fSJohn Wang * @return The table, std::nullopt if loading fails 265d965934fSJohn Wang */ 266d965934fSJohn Wang std::optional<Table> loadTable(const fs::path& path); 2678241b340SJohn Wang 268cac0ebb2SSagar Srinivas /** @brief Method to decode the attribute name from the string handle 269cac0ebb2SSagar Srinivas * 270cac0ebb2SSagar Srinivas * @param[in] stringEntry - string entry from string table 271cac0ebb2SSagar Srinivas * @return the decoded string 272cac0ebb2SSagar Srinivas */ 273cac0ebb2SSagar Srinivas std::string decodeStringFromStringEntry( 274cac0ebb2SSagar Srinivas const pldm_bios_string_table_entry* stringEntry); 275cac0ebb2SSagar Srinivas 276cac0ebb2SSagar Srinivas /** @brief Method to print the string Handle by passing the attribute Handle 277cac0ebb2SSagar Srinivas * of the bios attribute that got updated 278cac0ebb2SSagar Srinivas * 279cac0ebb2SSagar Srinivas * @param[in] handle - the Attribute handle of the bios attribute 280cac0ebb2SSagar Srinivas * @param[in] index - index to the possible value handles 281cac0ebb2SSagar Srinivas * @param[in] attrTable - the attribute table 282cac0ebb2SSagar Srinivas * @param[in] stringTable - the string table 283cac0ebb2SSagar Srinivas * @return string handle from the string table and decoded string to the 284cac0ebb2SSagar Srinivas * name handle 285cac0ebb2SSagar Srinivas */ 286cac0ebb2SSagar Srinivas std::string displayStringHandle(uint16_t handle, uint8_t index, 287cac0ebb2SSagar Srinivas const std::optional<Table>& attrTable, 288cac0ebb2SSagar Srinivas const std::optional<Table>& stringTable); 289cac0ebb2SSagar Srinivas 290cac0ebb2SSagar Srinivas /** @brief Method to trace the bios attribute which got changed 291cac0ebb2SSagar Srinivas * 292cac0ebb2SSagar Srinivas * @param[in] attrValueEntry - The attribute value entry to update 293cac0ebb2SSagar Srinivas * @param[in] attrEntry - The attribute table entry 294cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 295cac0ebb2SSagar Srinivas */ 296cac0ebb2SSagar Srinivas void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry, 297cac0ebb2SSagar Srinivas const pldm_bios_attr_table_entry* attrEntry, 298cac0ebb2SSagar Srinivas bool isBMC); 299cac0ebb2SSagar Srinivas 3008241b340SJohn Wang /** @brief Check the attribute value to update 3018241b340SJohn Wang * @param[in] attrValueEntry - The attribute value entry to update 3028241b340SJohn Wang * @param[in] attrEntry - The attribute table entry 3038241b340SJohn Wang * @param[in] stringTable - The string table 3048241b340SJohn Wang * @return pldm_completion_codes 3058241b340SJohn Wang */ 3068241b340SJohn Wang int checkAttrValueToUpdate( 3078241b340SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry, 3088241b340SJohn Wang const pldm_bios_attr_table_entry* attrEntry, Table& stringTable); 3091b180d8aSGeorge Liu 3101b180d8aSGeorge Liu /** @brief Check the attribute table 3111b180d8aSGeorge Liu * @param[in] table - The table 3121b180d8aSGeorge Liu * @return pldm_completion_codes 3131b180d8aSGeorge Liu */ 3141b180d8aSGeorge Liu int checkAttributeTable(const Table& table); 3151b180d8aSGeorge Liu 3161b180d8aSGeorge Liu /** @brief Check the attribute value table 3171b180d8aSGeorge Liu * @param[in] table - The table 3181b180d8aSGeorge Liu * @return pldm_completion_codes 3191b180d8aSGeorge Liu */ 3201b180d8aSGeorge Liu int checkAttributeValueTable(const Table& table); 3211b180d8aSGeorge Liu 3221b180d8aSGeorge Liu /** @brief Update the BaseBIOSTable property of the D-Bus interface 3231b180d8aSGeorge Liu */ 3241b180d8aSGeorge Liu void updateBaseBIOSTableProperty(); 3251244acfdSGeorge Liu 3261244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface and 3271244acfdSGeorge Liu * update BaseBIOSTable 3281244acfdSGeorge Liu */ 3291244acfdSGeorge Liu void listenPendingAttributes(); 3301244acfdSGeorge Liu 3311244acfdSGeorge Liu /** @brief Find attribute handle from bios attribute table 3321244acfdSGeorge Liu * @param[in] attrName - attribute name 3331244acfdSGeorge Liu * @return attribute handle 3341244acfdSGeorge Liu */ 3351244acfdSGeorge Liu uint16_t findAttrHandle(const std::string& attrName); 3361244acfdSGeorge Liu 3371244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface 3381244acfdSGeorge Liu * and update BaseBIOSTable 3391244acfdSGeorge Liu * @param[in] msg - Data associated with subscribed signal 3401244acfdSGeorge Liu */ 3411244acfdSGeorge Liu void constructPendingAttribute(const PendingAttributes& pendingAttributes); 342d965934fSJohn Wang }; 343d965934fSJohn Wang 344d965934fSJohn Wang } // namespace bios 345d965934fSJohn Wang } // namespace responder 346d965934fSJohn Wang } // namespace pldm 347