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