xref: /openbmc/pldm/fw-update/update_manager.hpp (revision 366507c82a4781c4a893ab9b9ca7b38f2157a353)
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