blob: 5aa80ec1da229baf7f799bb2701a55e9250d98fe [file] [log] [blame]
Tom Joseph4d8d5772021-08-17 07:35:05 -07001#pragma once
2
Andrew Jeffery2abbce72023-10-18 10:17:35 +10303#include "common/instance_id.hpp"
Tom Joseph4d8d5772021-08-17 07:35:05 -07004#include "common/types.hpp"
5#include "device_updater.hpp"
Andrew Jefferyf106a2c2024-07-25 21:45:41 +09306#include "fw-update/activation.hpp"
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +05307#include "fw-update/update.hpp"
8#ifdef FW_UPDATE_INOTIFY_ENABLED
9#include "fw-update/watch.hpp"
10#endif
Tom Joseph4d8d5772021-08-17 07:35:05 -070011#include "package_parser.hpp"
Tom Joseph4d8d5772021-08-17 07:35:05 -070012#include "requester/handler.hpp"
Tom Joseph4d8d5772021-08-17 07:35:05 -070013
George Liuc453e162022-12-21 17:16:23 +080014#include <libpldm/base.h>
George Liuc453e162022-12-21 17:16:23 +080015
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +053016#include <sdbusplus/async.hpp>
17#include <sdbusplus/server/object.hpp>
18#include <xyz/openbmc_project/Software/Activation/server.hpp>
19
Tom Joseph4d8d5772021-08-17 07:35:05 -070020#include <chrono>
21#include <filesystem>
22#include <fstream>
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +053023#include <sstream>
Tom Joseph4d8d5772021-08-17 07:35:05 -070024#include <tuple>
25#include <unordered_map>
26
27namespace pldm
28{
29
30namespace fw_update
31{
32
33using namespace sdeventplus;
34using namespace sdeventplus::source;
Tom Joseph4d8d5772021-08-17 07:35:05 -070035using namespace pldm;
36
37using DeviceIDRecordOffset = size_t;
38using DeviceUpdaterInfo = std::pair<mctp_eid_t, DeviceIDRecordOffset>;
39using DeviceUpdaterInfos = std::vector<DeviceUpdaterInfo>;
40using TotalComponentUpdates = size_t;
41
Tom Joseph4d8d5772021-08-17 07:35:05 -070042class UpdateManager
43{
44 public:
45 UpdateManager() = delete;
46 UpdateManager(const UpdateManager&) = delete;
47 UpdateManager(UpdateManager&&) = delete;
48 UpdateManager& operator=(const UpdateManager&) = delete;
49 UpdateManager& operator=(UpdateManager&&) = delete;
50 ~UpdateManager() = default;
51
52 explicit UpdateManager(
53 Event& event,
54 pldm::requester::Handler<pldm::requester::Request>& handler,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093055 InstanceIdDb& instanceIdDb, const DescriptorMap& descriptorMap,
Tom Joseph4d8d5772021-08-17 07:35:05 -070056 const ComponentInfoMap& componentInfoMap) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040057 event(event), handler(handler), instanceIdDb(instanceIdDb),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093058 descriptorMap(descriptorMap), componentInfoMap(componentInfoMap),
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +053059#ifdef FW_UPDATE_INOTIFY_ENABLED
Tom Joseph4d8d5772021-08-17 07:35:05 -070060 watch(event.get(),
Eric Yang70eca962025-05-11 01:48:15 +080061 [this](std::string& packageFilePath) {
62 return this->processPackage(
63 std::filesystem::path(packageFilePath));
64 }),
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +053065#else
66 updater(std::make_unique<Update>(pldm::utils::DBusHandler::getBus(),
67 "/xyz/openbmc_project/software/pldm",
68 this)),
69#endif
DelphineCCChiu312c3732024-04-24 08:49:51 +080070 totalNumComponentUpdates(0), compUpdateCompletedCount(0)
Tom Joseph4d8d5772021-08-17 07:35:05 -070071 {}
72
73 /** @brief Handle PLDM request for the commands in the FW update
74 * specification
75 *
76 * @param[in] eid - Remote MCTP Endpoint ID
77 * @param[in] command - PLDM command code
78 * @param[in] request - PLDM request message
79 * @param[in] requestLen - PLDM request message length
80 *
81 * @return PLDM response message
82 */
83 Response handleRequest(mctp_eid_t eid, uint8_t command,
84 const pldm_msg* request, size_t reqMsgLen);
85
86 int processPackage(const std::filesystem::path& packageFilePath);
87
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +053088 /** @brief Process the firmware update package
89 *
90 * @param[in] packageStream - Stream of the firmware update package
91 * @param[in] packageSize - Size of the firmware update package
92 *
93 * @return Object path of the created Software object
94 */
95 void processStream(std::istream& packageStream, uintmax_t packageSize);
96
97 /** @brief Defers processing the package stream
98 *
99 * @param[in] packageStream - Stream of the firmware update package
100 * @param[in] packageSize - Size of the firmware update package
101 *
102 * @return Object path of the created Software object as a string
103 */
104 std::string processStreamDefer(std::istream& packageStream,
105 uintmax_t packageSize);
106
Tom Joseph4d8d5772021-08-17 07:35:05 -0700107 void updateDeviceCompletion(mctp_eid_t eid, bool status);
108
109 void updateActivationProgress();
110
111 /** @brief Callback function that will be invoked when the
112 * RequestedActivation will be set to active in the Activation
113 * interface
114 */
115 void activatePackage();
116
117 void clearActivationInfo();
118
119 /** @brief
120 *
121 */
Patrick Williams366507c2025-02-03 14:28:01 -0500122 DeviceUpdaterInfos associatePkgToDevices(
123 const FirmwareDeviceIDRecords& fwDeviceIDRecords,
124 const DescriptorMap& descriptorMap,
125 TotalComponentUpdates& totalNumComponentUpdates);
Tom Joseph4d8d5772021-08-17 07:35:05 -0700126
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +0530127 /** @brief Generate a unique software ID based on current timestamp
128 *
129 * @return String representation of the current timestamp in seconds
130 */
131 static std::string getSwId();
132
Tom Joseph4d8d5772021-08-17 07:35:05 -0700133 const std::string swRootPath{"/xyz/openbmc_project/software/"};
Tom Joseph4d8d5772021-08-17 07:35:05 -0700134 Event& event; //!< reference to PLDM daemon's main event loop
135 /** @brief PLDM request handler */
136 pldm::requester::Handler<pldm::requester::Request>& handler;
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930137 InstanceIdDb& instanceIdDb; //!< reference to an InstanceIdDb
Tom Josephb7e083e2021-10-26 15:10:03 +0530138
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +0530139 std::unique_ptr<Activation> activation;
140
Tom Josephb7e083e2021-10-26 15:10:03 +0530141 private:
Tom Joseph4d8d5772021-08-17 07:35:05 -0700142 /** @brief Device identifiers of the managed FDs */
143 const DescriptorMap& descriptorMap;
144 /** @brief Component information needed for the update of the managed FDs */
145 const ComponentInfoMap& componentInfoMap;
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +0530146#ifdef FW_UPDATE_INOTIFY_ENABLED
Tom Joseph4d8d5772021-08-17 07:35:05 -0700147 Watch watch;
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +0530148#else
149 std::unique_ptr<Update> updater;
150#endif
Tom Joseph4d8d5772021-08-17 07:35:05 -0700151
Tom Joseph4d8d5772021-08-17 07:35:05 -0700152 std::unique_ptr<ActivationProgress> activationProgress;
153 std::string objPath;
154
155 std::filesystem::path fwPackageFilePath;
156 std::unique_ptr<PackageParser> parser;
157 std::ifstream package;
158
159 std::unordered_map<mctp_eid_t, std::unique_ptr<DeviceUpdater>>
160 deviceUpdaterMap;
161 std::unordered_map<mctp_eid_t, bool> deviceUpdateCompletionMap;
162
163 /** @brief Total number of component updates to calculate the progress of
164 * the Firmware activation
165 */
166 size_t totalNumComponentUpdates;
167
168 /** @brief FW update package can contain updates for multiple firmware
169 * devices and each device can have multiple components. Once
170 * each component is updated (Transfer completed, Verified and
171 * Applied) ActivationProgress is updated.
172 */
173 size_t compUpdateCompletedCount;
174 decltype(std::chrono::steady_clock::now()) startTime;
P Arun Kumar Reddy6a3f9902025-03-26 10:23:06 +0530175 std::unique_ptr<sdeventplus::source::Defer> updateDeferHandler;
Tom Joseph4d8d5772021-08-17 07:35:05 -0700176};
177
178} // namespace fw_update
179
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930180} // namespace pldm