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