14d8d5770STom Joseph #pragma once 24d8d5770STom Joseph 32abbce76SAndrew Jeffery #include "common/instance_id.hpp" 44d8d5770STom Joseph #include "common/types.hpp" 54d8d5770STom Joseph #include "device_updater.hpp" 6f106a2c8SAndrew Jeffery #include "fw-update/activation.hpp" 74d8d5770STom Joseph #include "package_parser.hpp" 84d8d5770STom Joseph #include "requester/handler.hpp" 94d8d5770STom Joseph #include "watch.hpp" 104d8d5770STom Joseph 11c453e164SGeorge Liu #include <libpldm/base.h> 12c453e164SGeorge Liu 134d8d5770STom Joseph #include <chrono> 144d8d5770STom Joseph #include <filesystem> 154d8d5770STom Joseph #include <fstream> 164d8d5770STom Joseph #include <tuple> 174d8d5770STom Joseph #include <unordered_map> 184d8d5770STom Joseph 194d8d5770STom Joseph namespace pldm 204d8d5770STom Joseph { 214d8d5770STom Joseph 224d8d5770STom Joseph namespace fw_update 234d8d5770STom Joseph { 244d8d5770STom Joseph 254d8d5770STom Joseph using namespace sdeventplus; 264d8d5770STom Joseph using namespace sdeventplus::source; 274d8d5770STom Joseph using namespace pldm; 284d8d5770STom Joseph 294d8d5770STom Joseph using DeviceIDRecordOffset = size_t; 304d8d5770STom Joseph using DeviceUpdaterInfo = std::pair<mctp_eid_t, DeviceIDRecordOffset>; 314d8d5770STom Joseph using DeviceUpdaterInfos = std::vector<DeviceUpdaterInfo>; 324d8d5770STom Joseph using TotalComponentUpdates = size_t; 334d8d5770STom Joseph 344d8d5770STom Joseph class UpdateManager 354d8d5770STom Joseph { 364d8d5770STom Joseph public: 374d8d5770STom Joseph UpdateManager() = delete; 384d8d5770STom Joseph UpdateManager(const UpdateManager&) = delete; 394d8d5770STom Joseph UpdateManager(UpdateManager&&) = delete; 404d8d5770STom Joseph UpdateManager& operator=(const UpdateManager&) = delete; 414d8d5770STom Joseph UpdateManager& operator=(UpdateManager&&) = delete; 424d8d5770STom Joseph ~UpdateManager() = default; 434d8d5770STom Joseph UpdateManager(Event & event,pldm::requester::Handler<pldm::requester::Request> & handler,InstanceIdDb & instanceIdDb,const DescriptorMap & descriptorMap,const ComponentInfoMap & componentInfoMap)444d8d5770STom Joseph explicit UpdateManager( 454d8d5770STom Joseph Event& event, 464d8d5770STom Joseph pldm::requester::Handler<pldm::requester::Request>& handler, 47a330b2f0SAndrew Jeffery InstanceIdDb& instanceIdDb, const DescriptorMap& descriptorMap, 484d8d5770STom Joseph const ComponentInfoMap& componentInfoMap) : 4916c2a0a0SPatrick Williams event(event), handler(handler), instanceIdDb(instanceIdDb), 50a330b2f0SAndrew Jeffery descriptorMap(descriptorMap), componentInfoMap(componentInfoMap), 514d8d5770STom Joseph watch(event.get(), 52312c3735SDelphineCCChiu std::bind_front(&UpdateManager::processPackage, this)), 53312c3735SDelphineCCChiu totalNumComponentUpdates(0), compUpdateCompletedCount(0) 544d8d5770STom Joseph {} 554d8d5770STom Joseph 564d8d5770STom Joseph /** @brief Handle PLDM request for the commands in the FW update 574d8d5770STom Joseph * specification 584d8d5770STom Joseph * 594d8d5770STom Joseph * @param[in] eid - Remote MCTP Endpoint ID 604d8d5770STom Joseph * @param[in] command - PLDM command code 614d8d5770STom Joseph * @param[in] request - PLDM request message 624d8d5770STom Joseph * @param[in] requestLen - PLDM request message length 634d8d5770STom Joseph * 644d8d5770STom Joseph * @return PLDM response message 654d8d5770STom Joseph */ 664d8d5770STom Joseph Response handleRequest(mctp_eid_t eid, uint8_t command, 674d8d5770STom Joseph const pldm_msg* request, size_t reqMsgLen); 684d8d5770STom Joseph 694d8d5770STom Joseph int processPackage(const std::filesystem::path& packageFilePath); 704d8d5770STom Joseph 714d8d5770STom Joseph void updateDeviceCompletion(mctp_eid_t eid, bool status); 724d8d5770STom Joseph 734d8d5770STom Joseph void updateActivationProgress(); 744d8d5770STom Joseph 754d8d5770STom Joseph /** @brief Callback function that will be invoked when the 764d8d5770STom Joseph * RequestedActivation will be set to active in the Activation 774d8d5770STom Joseph * interface 784d8d5770STom Joseph */ 794d8d5770STom Joseph void activatePackage(); 804d8d5770STom Joseph 814d8d5770STom Joseph void clearActivationInfo(); 824d8d5770STom Joseph 834d8d5770STom Joseph /** @brief 844d8d5770STom Joseph * 854d8d5770STom Joseph */ 86*366507c8SPatrick Williams DeviceUpdaterInfos associatePkgToDevices( 87*366507c8SPatrick Williams const FirmwareDeviceIDRecords& fwDeviceIDRecords, 884d8d5770STom Joseph const DescriptorMap& descriptorMap, 894d8d5770STom Joseph TotalComponentUpdates& totalNumComponentUpdates); 904d8d5770STom Joseph 914d8d5770STom Joseph const std::string swRootPath{"/xyz/openbmc_project/software/"}; 924d8d5770STom Joseph Event& event; //!< reference to PLDM daemon's main event loop 934d8d5770STom Joseph /** @brief PLDM request handler */ 944d8d5770STom Joseph pldm::requester::Handler<pldm::requester::Request>& handler; 95a330b2f0SAndrew Jeffery InstanceIdDb& instanceIdDb; //!< reference to an InstanceIdDb 96b7e083eaSTom Joseph 97b7e083eaSTom Joseph private: 984d8d5770STom Joseph /** @brief Device identifiers of the managed FDs */ 994d8d5770STom Joseph const DescriptorMap& descriptorMap; 1004d8d5770STom Joseph /** @brief Component information needed for the update of the managed FDs */ 1014d8d5770STom Joseph const ComponentInfoMap& componentInfoMap; 1024d8d5770STom Joseph Watch watch; 1034d8d5770STom Joseph 1044d8d5770STom Joseph std::unique_ptr<Activation> activation; 1054d8d5770STom Joseph std::unique_ptr<ActivationProgress> activationProgress; 1064d8d5770STom Joseph std::string objPath; 1074d8d5770STom Joseph 1084d8d5770STom Joseph std::filesystem::path fwPackageFilePath; 1094d8d5770STom Joseph std::unique_ptr<PackageParser> parser; 1104d8d5770STom Joseph std::ifstream package; 1114d8d5770STom Joseph 1124d8d5770STom Joseph std::unordered_map<mctp_eid_t, std::unique_ptr<DeviceUpdater>> 1134d8d5770STom Joseph deviceUpdaterMap; 1144d8d5770STom Joseph std::unordered_map<mctp_eid_t, bool> deviceUpdateCompletionMap; 1154d8d5770STom Joseph 1164d8d5770STom Joseph /** @brief Total number of component updates to calculate the progress of 1174d8d5770STom Joseph * the Firmware activation 1184d8d5770STom Joseph */ 1194d8d5770STom Joseph size_t totalNumComponentUpdates; 1204d8d5770STom Joseph 1214d8d5770STom Joseph /** @brief FW update package can contain updates for multiple firmware 1224d8d5770STom Joseph * devices and each device can have multiple components. Once 1234d8d5770STom Joseph * each component is updated (Transfer completed, Verified and 1244d8d5770STom Joseph * Applied) ActivationProgress is updated. 1254d8d5770STom Joseph */ 1264d8d5770STom Joseph size_t compUpdateCompletedCount; 1274d8d5770STom Joseph decltype(std::chrono::steady_clock::now()) startTime; 1284d8d5770STom Joseph }; 1294d8d5770STom Joseph 1304d8d5770STom Joseph } // namespace fw_update 1314d8d5770STom Joseph 1324d8d5770STom Joseph } // namespace pldm 133