101539e7eSLei YU #pragma once 201539e7eSLei YU 301539e7eSLei YU #include "config.h" 401539e7eSLei YU 501539e7eSLei YU #include "activation.hpp" 67f2a2152SLei YU #include "association_interface.hpp" 791029448SLei YU #include "types.hpp" 85e0dcb39SLei YU #include "utils.hpp" 901539e7eSLei YU #include "version.hpp" 1001539e7eSLei YU 115e0dcb39SLei YU #include <phosphor-logging/log.hpp> 1201539e7eSLei YU #include <sdbusplus/server.hpp> 1391029448SLei YU #include <xyz/openbmc_project/Association/Definitions/server.hpp> 1401539e7eSLei YU #include <xyz/openbmc_project/Collection/DeleteAll/server.hpp> 1501539e7eSLei YU 165670b188SPatrick Williams #include <filesystem> 175670b188SPatrick Williams 18f77189f7SLei YU class TestItemUpdater; 19f77189f7SLei YU 2001539e7eSLei YU namespace phosphor 2101539e7eSLei YU { 2201539e7eSLei YU namespace software 2301539e7eSLei YU { 2401539e7eSLei YU namespace updater 2501539e7eSLei YU { 2601539e7eSLei YU 2701539e7eSLei YU class Version; 2801539e7eSLei YU 29374fae56SPatrick Williams using ItemUpdaterInherit = sdbusplus::server::object_t< 30a5c47bb3SLei YU sdbusplus::xyz::openbmc_project::Association::server::Definitions>; 31a5c47bb3SLei YU 3201539e7eSLei YU namespace MatchRules = sdbusplus::bus::match::rules; 3301539e7eSLei YU 3458c26e3fSLei YU namespace fs = std::filesystem; 3558c26e3fSLei YU 3601539e7eSLei YU /** @class ItemUpdater 3701539e7eSLei YU * @brief Manages the activation of the PSU version items. 3801539e7eSLei YU */ 395670b188SPatrick Williams class ItemUpdater : 405670b188SPatrick Williams public ItemUpdaterInherit, 41ffb36539SLei YU public AssociationInterface, 42ffb36539SLei YU public ActivationListener 4301539e7eSLei YU { 44f77189f7SLei YU friend class ::TestItemUpdater; 45f77189f7SLei YU 4601539e7eSLei YU public: 4701539e7eSLei YU /** @brief Constructs ItemUpdater 4801539e7eSLei YU * 4901539e7eSLei YU * @param[in] bus - The D-Bus bus object 5001539e7eSLei YU * @param[in] path - The D-Bus path 5101539e7eSLei YU */ 52374fae56SPatrick Williams ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) : 5301539e7eSLei YU ItemUpdaterInherit(bus, path.c_str()), bus(bus), 54bab5ed99SPatrick Williams versionMatch( 55bab5ed99SPatrick Williams bus, 56bab5ed99SPatrick Williams MatchRules::interfacesAdded() + MatchRules::path(SOFTWARE_OBJPATH), 57bab5ed99SPatrick Williams std::bind(std::mem_fn(&ItemUpdater::createActivation), this, 58bab5ed99SPatrick Williams std::placeholders::_1)), 59760053d8SFaisal Awada psuInterfaceMatch( 60760053d8SFaisal Awada bus, 61760053d8SFaisal Awada MatchRules::interfacesAdded() + 62760053d8SFaisal Awada MatchRules::path("/xyz/openbmc_project/inventory") + 63760053d8SFaisal Awada MatchRules::sender("xyz.openbmc_project.Inventory.Manager"), 64760053d8SFaisal Awada std::bind(std::mem_fn(&ItemUpdater::onPSUInterfaceAdded), this, 65760053d8SFaisal Awada std::placeholders::_1)) 6601539e7eSLei YU { 67760053d8SFaisal Awada processPSUImageAndSyncToLatest(); 6801539e7eSLei YU } 6901539e7eSLei YU 7001539e7eSLei YU /** @brief Deletes version 7101539e7eSLei YU * 7201539e7eSLei YU * @param[in] versionId - Id of the version to delete 7301539e7eSLei YU */ 74a5c47bb3SLei YU void erase(const std::string& versionId); 7501539e7eSLei YU 7691029448SLei YU /** @brief Creates an active association to the 7791029448SLei YU * newly active software image 7891029448SLei YU * 7991029448SLei YU * @param[in] path - The path to create the association to. 8091029448SLei YU */ 817f2a2152SLei YU void createActiveAssociation(const std::string& path) override; 8291029448SLei YU 83ad90ad51SLei YU /** @brief Add the functional association to the 8491029448SLei YU * new "running" PSU images 8591029448SLei YU * 86ad90ad51SLei YU * @param[in] path - The path to add the association to. 8791029448SLei YU */ 887f2a2152SLei YU void addFunctionalAssociation(const std::string& path) override; 8991029448SLei YU 90a8b966f1SLei YU /** @brief Add the updateable association to the 91a8b966f1SLei YU * "running" PSU software image 92a8b966f1SLei YU * 93a8b966f1SLei YU * @param[in] path - The path to create the association. 94a8b966f1SLei YU */ 95a8b966f1SLei YU void addUpdateableAssociation(const std::string& path) override; 96a8b966f1SLei YU 9791029448SLei YU /** @brief Removes the associations from the provided software image path 9891029448SLei YU * 9991029448SLei YU * @param[in] path - The path to remove the association from. 10091029448SLei YU */ 1017f2a2152SLei YU void removeAssociation(const std::string& path) override; 10291029448SLei YU 103ffb36539SLei YU /** @brief Notify a PSU is updated 104ffb36539SLei YU * 105ffb36539SLei YU * @param[in] versionId - The versionId of the activation 106ffb36539SLei YU * @param[in] psuInventoryPath - The PSU inventory path that is updated 107ffb36539SLei YU */ 108ffb36539SLei YU void onUpdateDone(const std::string& versionId, 109ffb36539SLei YU const std::string& psuInventoryPath) override; 110ffb36539SLei YU 1117f2a2152SLei YU private: 11201539e7eSLei YU /** @brief Callback function for Software.Version match. 11301539e7eSLei YU * @details Creates an Activation D-Bus object. 11401539e7eSLei YU * 11501539e7eSLei YU * @param[in] msg - Data associated with subscribed signal 11601539e7eSLei YU */ 117374fae56SPatrick Williams void createActivation(sdbusplus::message_t& msg); 11801539e7eSLei YU 119a2c2cd72SLei YU using Properties = 120a2c2cd72SLei YU std::map<std::string, utils::UtilsInterface::PropertyType>; 121a2c2cd72SLei YU 122ad90ad51SLei YU /** @brief Callback function for PSU inventory match. 123ad90ad51SLei YU * @details Update an Activation D-Bus object for PSU inventory. 124ad90ad51SLei YU * 125ad90ad51SLei YU * @param[in] msg - Data associated with subscribed signal 126ad90ad51SLei YU */ 127374fae56SPatrick Williams void onPsuInventoryChangedMsg(sdbusplus::message_t& msg); 128a2c2cd72SLei YU 129a2c2cd72SLei YU /** @brief Callback function for PSU inventory match. 130a2c2cd72SLei YU * @details Update an Activation D-Bus object for PSU inventory. 131a2c2cd72SLei YU * 132a2c2cd72SLei YU * @param[in] psuPath - The PSU inventory path 133a2c2cd72SLei YU * @param[in] properties - The updated properties 134a2c2cd72SLei YU */ 135a2c2cd72SLei YU void onPsuInventoryChanged(const std::string& psuPath, 136a2c2cd72SLei YU const Properties& properties); 137ad90ad51SLei YU 13801539e7eSLei YU /** @brief Create Activation object */ 13901539e7eSLei YU std::unique_ptr<Activation> createActivationObject( 14001539e7eSLei YU const std::string& path, const std::string& versionId, 14158c26e3fSLei YU const std::string& extVersion, Activation::Status activationStatus, 1429930137bSLei YU const AssociationList& assocs, const std::string& filePath); 14301539e7eSLei YU 14401539e7eSLei YU /** @brief Create Version object */ 145bab5ed99SPatrick Williams std::unique_ptr<Version> createVersionObject( 146bab5ed99SPatrick Williams const std::string& objPath, const std::string& versionId, 14701539e7eSLei YU const std::string& versionString, 148bab5ed99SPatrick Williams sdbusplus::xyz::openbmc_project::Software::server::Version:: 149bab5ed99SPatrick Williams VersionPurpose versionPurpose); 15001539e7eSLei YU 151bd3b0076SLei YU /** @brief Create Activation and Version object for PSU inventory 152bd3b0076SLei YU * @details If the same version exists for multiple PSUs, just add 153bd3b0076SLei YU * related association, instead of creating new objects. 154bd3b0076SLei YU * */ 155ad90ad51SLei YU void createPsuObject(const std::string& psuInventoryPath, 156ad90ad51SLei YU const std::string& psuVersion); 157ad90ad51SLei YU 158bd3b0076SLei YU /** @brief Remove Activation and Version object for PSU inventory 15933cf9f08SManojkiran Eda * @details If the same version exists for multiple PSUs, just remove 160bd3b0076SLei YU * related association. 161bd3b0076SLei YU * If the version has no association, the Activation and 162bd3b0076SLei YU * Version object will be removed 163bd3b0076SLei YU */ 164bd3b0076SLei YU void removePsuObject(const std::string& psuInventoryPath); 165bd3b0076SLei YU 16673a6f0d8SShawn McCarney /** @brief Add PSU inventory path to the PSU status map 167*783406e6SShawn McCarney * @details Also adds a PropertiesChanged listener for the inventory path 168*783406e6SShawn McCarney * so we are notified when the Present property changes. 16973a6f0d8SShawn McCarney * Does nothing if the inventory path already exists in the map. 17073a6f0d8SShawn McCarney * 17173a6f0d8SShawn McCarney * @param[in] psuPath - The PSU inventory path 17273a6f0d8SShawn McCarney */ 17373a6f0d8SShawn McCarney void addPsuToStatusMap(const std::string& psuPath); 17473a6f0d8SShawn McCarney 175*783406e6SShawn McCarney /** @brief Handle a change in presence for a PSU. 176*783406e6SShawn McCarney * 177*783406e6SShawn McCarney * @param[in] psuPath - The PSU inventory path 178*783406e6SShawn McCarney */ 179*783406e6SShawn McCarney void handlePSUPresenceChanged(const std::string& psuPath); 180*783406e6SShawn McCarney 181ad90ad51SLei YU /** 182ad90ad51SLei YU * @brief Create and populate the active PSU Version. 183ad90ad51SLei YU */ 184ad90ad51SLei YU void processPSUImage(); 185ad90ad51SLei YU 18658c26e3fSLei YU /** @brief Create PSU Version from stored images */ 18758c26e3fSLei YU void processStoredImage(); 18858c26e3fSLei YU 18958c26e3fSLei YU /** @brief Scan a directory and create PSU Version from stored images */ 19058c26e3fSLei YU void scanDirectory(const fs::path& p); 19158c26e3fSLei YU 1926520748dSLei YU /** @brief Get the versionId of the latest PSU version */ 1936520748dSLei YU std::optional<std::string> getLatestVersionId(); 1946520748dSLei YU 19563f9e712SLei YU /** @brief Update PSUs to the latest version */ 19663f9e712SLei YU void syncToLatestImage(); 19763f9e712SLei YU 19863f9e712SLei YU /** @brief Invoke the activation via DBus */ 19980c2daaeSGeorge Liu static void invokeActivation(const std::unique_ptr<Activation>& activation); 20063f9e712SLei YU 201760053d8SFaisal Awada /** @brief Callback function for interfaces added signal. 202760053d8SFaisal Awada * 203760053d8SFaisal Awada * This method is called when a new interface is added. It updates the 204760053d8SFaisal Awada * internal status map and process the new PSU if it's present. 205760053d8SFaisal Awada * 206760053d8SFaisal Awada * @param[in] msg - Data associated with subscribed signal 207760053d8SFaisal Awada */ 208760053d8SFaisal Awada void onPSUInterfaceAdded(sdbusplus::message_t& msg); 209760053d8SFaisal Awada 210760053d8SFaisal Awada /** 211760053d8SFaisal Awada * @brief Handles the processing of PSU images. 212760053d8SFaisal Awada * 213760053d8SFaisal Awada * This function responsible for invoking the sequence of processing PSU 214760053d8SFaisal Awada * images, processing stored images, and syncing to the latest firmware 215760053d8SFaisal Awada * image. 216760053d8SFaisal Awada */ 217760053d8SFaisal Awada void processPSUImageAndSyncToLatest(); 218760053d8SFaisal Awada 219fb86e794SFaisal Awada /** @brief Retrieve FW version from IMG_DIR_BUILTIN 220fb86e794SFaisal Awada * 221fb86e794SFaisal Awada * This function retrieves the firmware version from the PSU model directory 222fb86e794SFaisal Awada * that is in the IMG_DIR_BUILTIN. It loops through the activations map to 223fb86e794SFaisal Awada * find matching path starts with IMG_DIR_BUILTIN, then gets the 224fb86e794SFaisal Awada * corresponding version ID, and then looks it up in the versions map to 225fb86e794SFaisal Awada * retrieve the associated version string. 226fb86e794SFaisal Awada */ 227fb86e794SFaisal Awada std::string getFWVersionFromBuiltinDir(); 228fb86e794SFaisal Awada 22901539e7eSLei YU /** @brief Persistent sdbusplus D-Bus bus connection. */ 230374fae56SPatrick Williams sdbusplus::bus_t& bus; 23101539e7eSLei YU 23201539e7eSLei YU /** @brief Persistent map of Activation D-Bus objects and their 23301539e7eSLei YU * version id */ 23401539e7eSLei YU std::map<std::string, std::unique_ptr<Activation>> activations; 23501539e7eSLei YU 23601539e7eSLei YU /** @brief Persistent map of Version D-Bus objects and their 23701539e7eSLei YU * version id */ 23801539e7eSLei YU std::map<std::string, std::unique_ptr<Version>> versions; 23901539e7eSLei YU 240bd3b0076SLei YU /** @brief The reference map of PSU Inventory objects and the 241bd3b0076SLei YU * Activation*/ 242bd3b0076SLei YU std::map<std::string, const std::unique_ptr<Activation>&> 243bd3b0076SLei YU psuPathActivationMap; 244bd3b0076SLei YU 245ad90ad51SLei YU /** @brief sdbusplus signal match for PSU Software*/ 24601539e7eSLei YU sdbusplus::bus::match_t versionMatch; 24791029448SLei YU 248ad90ad51SLei YU /** @brief sdbusplus signal matches for PSU Inventory */ 249ad90ad51SLei YU std::vector<sdbusplus::bus::match_t> psuMatches; 250ad90ad51SLei YU 25191029448SLei YU /** @brief This entry's associations */ 25291029448SLei YU AssociationList assocs; 2536520748dSLei YU 2546520748dSLei YU /** @brief A collection of the version strings */ 2556520748dSLei YU std::set<std::string> versionStrings; 2561517f5f6SLei YU 2571517f5f6SLei YU /** @brief A struct to hold the PSU present status and model */ 2581517f5f6SLei YU struct psuStatus 2591517f5f6SLei YU { 2601517f5f6SLei YU bool present; 2611517f5f6SLei YU std::string model; 2621517f5f6SLei YU }; 2631517f5f6SLei YU 2641517f5f6SLei YU /** @brief The map of PSU inventory path and the psuStatus 2651517f5f6SLei YU * 2661517f5f6SLei YU * It is used to handle psu inventory changed event, that only create psu 2671517f5f6SLei YU * software object when a PSU is present and the model is retrieved */ 2681517f5f6SLei YU std::map<std::string, psuStatus> psuStatusMap; 269760053d8SFaisal Awada 270760053d8SFaisal Awada /** @brief Signal match for PSU interfaces added. 271760053d8SFaisal Awada * 272760053d8SFaisal Awada * This match listens for D-Bus signals indicating new interface has been 273760053d8SFaisal Awada * added. When such a signal received, it triggers the 274760053d8SFaisal Awada * `onInterfacesAdded` method to handle the new PSU. 275760053d8SFaisal Awada */ 276760053d8SFaisal Awada sdbusplus::bus::match_t psuInterfaceMatch; 27701539e7eSLei YU }; 27801539e7eSLei YU 27901539e7eSLei YU } // namespace updater 28001539e7eSLei YU } // namespace software 28101539e7eSLei YU } // namespace phosphor 282