1 #pragma once 2 3 #include "libpldm/base.h" 4 #include "libpldm/requester/pldm.h" 5 6 #include "common/types.hpp" 7 #include "device_updater.hpp" 8 #include "package_parser.hpp" 9 #include "pldmd/dbus_impl_requester.hpp" 10 #include "requester/handler.hpp" 11 #include "watch.hpp" 12 13 #include <chrono> 14 #include <filesystem> 15 #include <fstream> 16 #include <tuple> 17 #include <unordered_map> 18 19 namespace pldm 20 { 21 22 namespace fw_update 23 { 24 25 using namespace sdeventplus; 26 using namespace sdeventplus::source; 27 using namespace pldm::dbus_api; 28 using namespace pldm; 29 30 using DeviceIDRecordOffset = size_t; 31 using DeviceUpdaterInfo = std::pair<mctp_eid_t, DeviceIDRecordOffset>; 32 using DeviceUpdaterInfos = std::vector<DeviceUpdaterInfo>; 33 using TotalComponentUpdates = size_t; 34 35 class Activation; 36 class ActivationProgress; 37 38 class UpdateManager 39 { 40 public: 41 UpdateManager() = delete; 42 UpdateManager(const UpdateManager&) = delete; 43 UpdateManager(UpdateManager&&) = delete; 44 UpdateManager& operator=(const UpdateManager&) = delete; 45 UpdateManager& operator=(UpdateManager&&) = delete; 46 ~UpdateManager() = default; 47 48 explicit UpdateManager( 49 Event& event, 50 pldm::requester::Handler<pldm::requester::Request>& handler, 51 Requester& requester, const DescriptorMap& descriptorMap, 52 const ComponentInfoMap& componentInfoMap) : 53 event(event), 54 handler(handler), requester(requester), descriptorMap(descriptorMap), 55 componentInfoMap(componentInfoMap), 56 watch(event.get(), 57 std::bind_front(&UpdateManager::processPackage, this)) 58 {} 59 60 /** @brief Handle PLDM request for the commands in the FW update 61 * specification 62 * 63 * @param[in] eid - Remote MCTP Endpoint ID 64 * @param[in] command - PLDM command code 65 * @param[in] request - PLDM request message 66 * @param[in] requestLen - PLDM request message length 67 * 68 * @return PLDM response message 69 */ 70 Response handleRequest(mctp_eid_t eid, uint8_t command, 71 const pldm_msg* request, size_t reqMsgLen); 72 73 int processPackage(const std::filesystem::path& packageFilePath); 74 75 void updateDeviceCompletion(mctp_eid_t eid, bool status); 76 77 void updateActivationProgress(); 78 79 /** @brief Callback function that will be invoked when the 80 * RequestedActivation will be set to active in the Activation 81 * interface 82 */ 83 void activatePackage(); 84 85 void clearActivationInfo(); 86 87 /** @brief 88 * 89 */ 90 DeviceUpdaterInfos 91 associatePkgToDevices(const FirmwareDeviceIDRecords& fwDeviceIDRecords, 92 const DescriptorMap& descriptorMap, 93 TotalComponentUpdates& totalNumComponentUpdates); 94 95 const std::string swRootPath{"/xyz/openbmc_project/software/"}; 96 Event& event; //!< reference to PLDM daemon's main event loop 97 /** @brief PLDM request handler */ 98 pldm::requester::Handler<pldm::requester::Request>& handler; 99 Requester& requester; //!< reference to Requester object 100 101 private: 102 /** @brief Device identifiers of the managed FDs */ 103 const DescriptorMap& descriptorMap; 104 /** @brief Component information needed for the update of the managed FDs */ 105 const ComponentInfoMap& componentInfoMap; 106 Watch watch; 107 108 std::unique_ptr<Activation> activation; 109 std::unique_ptr<ActivationProgress> activationProgress; 110 std::string objPath; 111 112 std::filesystem::path fwPackageFilePath; 113 std::unique_ptr<PackageParser> parser; 114 std::ifstream package; 115 116 std::unordered_map<mctp_eid_t, std::unique_ptr<DeviceUpdater>> 117 deviceUpdaterMap; 118 std::unordered_map<mctp_eid_t, bool> deviceUpdateCompletionMap; 119 120 /** @brief Total number of component updates to calculate the progress of 121 * the Firmware activation 122 */ 123 size_t totalNumComponentUpdates; 124 125 /** @brief FW update package can contain updates for multiple firmware 126 * devices and each device can have multiple components. Once 127 * each component is updated (Transfer completed, Verified and 128 * Applied) ActivationProgress is updated. 129 */ 130 size_t compUpdateCompletedCount; 131 decltype(std::chrono::steady_clock::now()) startTime; 132 }; 133 134 } // namespace fw_update 135 136 } // namespace pldm