blob: 26a1de949856677c5ac39e7f95db6a8df40d34b0 [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"
Tom Joseph4d8d5772021-08-17 07:35:05 -07007#include "package_parser.hpp"
Tom Joseph4d8d5772021-08-17 07:35:05 -07008#include "requester/handler.hpp"
9#include "watch.hpp"
10
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/base.h>
George Liuc453e162022-12-21 17:16:23 +080012
Tom Joseph4d8d5772021-08-17 07:35:05 -070013#include <chrono>
14#include <filesystem>
15#include <fstream>
16#include <tuple>
17#include <unordered_map>
18
19namespace pldm
20{
21
22namespace fw_update
23{
24
25using namespace sdeventplus;
26using namespace sdeventplus::source;
Tom Joseph4d8d5772021-08-17 07:35:05 -070027using namespace pldm;
28
29using DeviceIDRecordOffset = size_t;
30using DeviceUpdaterInfo = std::pair<mctp_eid_t, DeviceIDRecordOffset>;
31using DeviceUpdaterInfos = std::vector<DeviceUpdaterInfo>;
32using TotalComponentUpdates = size_t;
33
Tom Joseph4d8d5772021-08-17 07:35:05 -070034class 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,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093047 InstanceIdDb& instanceIdDb, const DescriptorMap& descriptorMap,
Tom Joseph4d8d5772021-08-17 07:35:05 -070048 const ComponentInfoMap& componentInfoMap) :
49 event(event),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093050 handler(handler), instanceIdDb(instanceIdDb),
51 descriptorMap(descriptorMap), componentInfoMap(componentInfoMap),
Tom Joseph4d8d5772021-08-17 07:35:05 -070052 watch(event.get(),
DelphineCCChiu312c3732024-04-24 08:49:51 +080053 std::bind_front(&UpdateManager::processPackage, this)),
54 totalNumComponentUpdates(0), compUpdateCompletedCount(0)
Tom Joseph4d8d5772021-08-17 07:35:05 -070055 {}
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/"};
Tom Joseph4d8d5772021-08-17 07:35:05 -070093 Event& event; //!< reference to PLDM daemon's main event loop
94 /** @brief PLDM request handler */
95 pldm::requester::Handler<pldm::requester::Request>& handler;
Andrew Jefferya330b2f2023-05-04 14:55:37 +093096 InstanceIdDb& instanceIdDb; //!< reference to an InstanceIdDb
Tom Josephb7e083e2021-10-26 15:10:03 +053097
98 private:
Tom Joseph4d8d5772021-08-17 07:35:05 -070099 /** @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
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930133} // namespace pldm