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