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