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