xref: /openbmc/pldm/fw-update/update_manager.hpp (revision 8c6abca9)
1 #pragma once
2 
3 #include "common/types.hpp"
4 #include "device_updater.hpp"
5 #include "package_parser.hpp"
6 #include "pldmd/dbus_impl_requester.hpp"
7 #include "requester/handler.hpp"
8 #include "watch.hpp"
9 
10 #include <libpldm/base.h>
11 #include <libpldm/pldm.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::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
137