blob: 8b15dfd39d999e5b97aacc7ea6361a5b05601ab6 [file] [log] [blame]
Tom Josephef90b0d2021-08-17 07:12:49 -07001#pragma once
2
3#include "common/types.hpp"
4#include "requester/handler.hpp"
5#include "requester/request.hpp"
6
P Arun Kumar Reddy6fa09e92025-04-25 11:24:06 +05307#include <sdbusplus/timer.hpp>
Tom Josephef90b0d2021-08-17 07:12:49 -07008#include <sdeventplus/event.hpp>
9#include <sdeventplus/source/event.hpp>
10
11#include <fstream>
12
13namespace pldm
14{
15
16namespace fw_update
17{
18
P Arun Kumar Reddyd1c955b2025-04-15 16:06:06 +053019/** @brief Type alias for component update status tracking
20 * Maps component index to its update completion status (true indicates
21 * successful completion, false indicates cancellation)
22 */
23using ComponentUpdateStatusMap = std::map<size_t, bool>;
24
Tom Josephef90b0d2021-08-17 07:12:49 -070025class UpdateManager;
26
27/** @class DeviceUpdater
28 *
29 * DeviceUpdater orchestrates the firmware update of the firmware device and
30 * updates the UpdateManager about the status once it is complete.
31 */
32class DeviceUpdater
33{
34 public:
35 DeviceUpdater() = delete;
36 DeviceUpdater(const DeviceUpdater&) = delete;
37 DeviceUpdater(DeviceUpdater&&) = default;
38 DeviceUpdater& operator=(const DeviceUpdater&) = delete;
Pavithra Barithayaa7dbca52023-07-07 04:19:37 -050039 DeviceUpdater& operator=(DeviceUpdater&&) = delete;
Tom Josephef90b0d2021-08-17 07:12:49 -070040 ~DeviceUpdater() = default;
41
42 /** @brief Constructor
43 *
44 * @param[in] eid - Endpoint ID of the firmware device
Tom Josephef90b0d2021-08-17 07:12:49 -070045 * @param[in] package - File stream for firmware update package
46 * @param[in] fwDeviceIDRecord - FirmwareDeviceIDRecord in the fw update
47 * package that matches this firmware device
48 * @param[in] compImageInfos - Component image information for all the
49 * components in the fw update package
50 * @param[in] compInfo - Component info for the components in this FD
51 * derived from GetFirmwareParameters response
52 * @param[in] maxTransferSize - Maximum size in bytes of the variable
53 * payload allowed to be requested by the FD
54 * @param[in] updateManager - To update the status of fw update of the
55 * device
56 */
Tom Josephb7e083e2021-10-26 15:10:03 +053057 explicit DeviceUpdater(mctp_eid_t eid, std::ifstream& package,
58 const FirmwareDeviceIDRecord& fwDeviceIDRecord,
59 const ComponentImageInfos& compImageInfos,
60 const ComponentInfo& compInfo,
61 uint32_t maxTransferSize,
62 UpdateManager* updateManager) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040063 eid(eid), package(package), fwDeviceIDRecord(fwDeviceIDRecord),
Tom Josephb7e083e2021-10-26 15:10:03 +053064 compImageInfos(compImageInfos), compInfo(compInfo),
65 maxTransferSize(maxTransferSize), updateManager(updateManager)
Tom Josephef90b0d2021-08-17 07:12:49 -070066 {}
67
68 /** @brief Start the firmware update flow for the FD
69 *
70 * To start the update flow RequestUpdate command is sent to the FD.
71 *
72 */
73 void startFwUpdateFlow();
74
75 /** @brief Handler for RequestUpdate command response
76 *
77 * The response of the RequestUpdate is processed and if the response
78 * is success, send PassComponentTable request to FD.
79 *
80 * @param[in] eid - Remote MCTP endpoint
81 * @param[in] response - PLDM response message
82 * @param[in] respMsgLen - Response message length
83 */
84 void requestUpdate(mctp_eid_t eid, const pldm_msg* response,
85 size_t respMsgLen);
86
87 /** @brief Handler for PassComponentTable command response
88 *
89 * The response of the PassComponentTable is processed. If the response
90 * indicates component can be updated, continue with either a) or b).
91 *
92 * a. Send PassComponentTable request for the next component if
93 * applicable
94 * b. UpdateComponent command to request updating a specific
95 * firmware component
96 *
97 * If the response indicates component may be updateable, continue
98 * based on the policy in DeviceUpdateOptionFlags.
99 *
100 * @param[in] eid - Remote MCTP endpoint
101 * @param[in] response - PLDM response message
102 * @param[in] respMsgLen - Response message length
103 */
104 void passCompTable(mctp_eid_t eid, const pldm_msg* response,
105 size_t respMsgLen);
106
107 /** @brief Handler for UpdateComponent command response
108 *
109 * The response of the UpdateComponent is processed and will wait for
110 * FD to request the firmware data.
111 *
112 * @param[in] eid - Remote MCTP endpoint
113 * @param[in] response - PLDM response message
114 * @param[in] respMsgLen - Response message length
115 */
116 void updateComponent(mctp_eid_t eid, const pldm_msg* response,
117 size_t respMsgLen);
118
119 /** @brief Handler for RequestFirmwareData request
120 *
121 * @param[in] request - Request message
122 * @param[in] payload_length - Request message payload length
123 * @return Response - PLDM Response message
124 */
125 Response requestFwData(const pldm_msg* request, size_t payloadLength);
126
127 /** @brief Handler for TransferComplete request
128 *
129 * @param[in] request - Request message
130 * @param[in] payload_length - Request message payload length
131 * @return Response - PLDM Response message
132 */
133 Response transferComplete(const pldm_msg* request, size_t payloadLength);
134
135 /** @brief Handler for VerifyComplete request
136 *
137 * @param[in] request - Request message
138 * @param[in] payload_length - Request message payload length
139 * @return Response - PLDM Response message
140 */
141 Response verifyComplete(const pldm_msg* request, size_t payloadLength);
142
143 /** @brief Handler for ApplyComplete request
144 *
145 * @param[in] request - Request message
146 * @param[in] payload_length - Request message payload length
147 * @return Response - PLDM Response message
148 */
149 Response applyComplete(const pldm_msg* request, size_t payloadLength);
150
151 /** @brief Handler for ActivateFirmware command response
152 *
153 * The response of the ActivateFirmware is processed and will update the
154 * UpdateManager with the completion of the firmware update.
155 *
156 * @param[in] eid - Remote MCTP endpoint
157 * @param[in] response - PLDM response message
158 * @param[in] respMsgLen - Response message length
159 */
160 void activateFirmware(mctp_eid_t eid, const pldm_msg* response,
161 size_t respMsgLen);
P Arun Kumar Reddyd1c955b2025-04-15 16:06:06 +0530162 /**
163 * @brief Handler for CancelUpdateComponent command response
164 *
165 * @param[in] eid - Remote MCTP endpoint
166 * @param[in] response - PLDM Response message
167 * @param[in] respMsgLen - Response message length
168 */
169 void cancelUpdateComponent(mctp_eid_t eid, const pldm_msg* response,
170 size_t respMsgLen);
Tom Josephef90b0d2021-08-17 07:12:49 -0700171
172 private:
173 /** @brief Send PassComponentTable command request
174 *
175 * @param[in] compOffset - component offset in compImageInfos
176 */
177 void sendPassCompTableRequest(size_t offset);
178
179 /** @brief Send UpdateComponent command request
180 *
181 * @param[in] compOffset - component offset in compImageInfos
182 */
183 void sendUpdateComponentRequest(size_t offset);
184
185 /** @brief Send ActivateFirmware command request */
186 void sendActivateFirmwareRequest();
187
P Arun Kumar Reddyd1c955b2025-04-15 16:06:06 +0530188 /**
189 * @brief Send cancel update component request
190 */
191 void sendCancelUpdateComponentRequest();
192
P Arun Kumar Reddy6fa09e92025-04-25 11:24:06 +0530193 /**
194 * @brief Create a timer to handle RequestFirmwareData timeout (UA_T2)
195 */
196 void createRequestFwDataTimer();
197
Tom Josephef90b0d2021-08-17 07:12:49 -0700198 /** @brief Endpoint ID of the firmware device */
199 mctp_eid_t eid;
200
Tom Josephef90b0d2021-08-17 07:12:49 -0700201 /** @brief File stream for firmware update package */
202 std::ifstream& package;
203
204 /** @brief FirmwareDeviceIDRecord in the fw update package that matches this
205 * firmware device
206 */
207 const FirmwareDeviceIDRecord& fwDeviceIDRecord;
208
209 /** @brief Component image information for all the components in the fw
210 * update package
211 */
212 const ComponentImageInfos& compImageInfos;
213
214 /** @brief Component info for the components in this FD derived from
215 * GetFirmwareParameters response
216 */
217 const ComponentInfo& compInfo;
218
219 /** @brief Maximum size in bytes of the variable payload to be requested by
220 * the FD via RequestFirmwareData command
221 */
222 uint32_t maxTransferSize;
223
224 /** @brief To update the status of fw update of the FD */
225 UpdateManager* updateManager;
226
227 /** @brief Component index is used to track the current component being
228 * updated if multiple components are applicable for the FD.
229 * It is also used to keep track of the next component in
230 * PassComponentTable
231 */
232 size_t componentIndex = 0;
233
234 /** @brief To send a PLDM request after the current command handling */
235 std::unique_ptr<sdeventplus::source::Defer> pldmRequest;
P Arun Kumar Reddyd1c955b2025-04-15 16:06:06 +0530236
237 /**
238 * @brief Map to hold component update status. True - success, False -
239 * cancelled
240 */
241 ComponentUpdateStatusMap componentUpdateStatus;
P Arun Kumar Reddy6fa09e92025-04-25 11:24:06 +0530242
243 /**
244 * @brief Timeout in seconds for the UA to cancel the component update if no
245 * command is received from the FD during component image transfer stage
246 *
247 */
248 static constexpr int updateTimeoutSeconds = UPDATE_TIMEOUT_SECONDS;
249
250 /**
251 * @brief Timer to handle RequestFirmwareData timeout(UA_T2)
252 *
253 */
254 std::unique_ptr<sdbusplus::Timer> reqFwDataTimer;
Tom Josephef90b0d2021-08-17 07:12:49 -0700255};
256
257} // namespace fw_update
258
Patrick Williams6da4f912023-05-10 07:50:53 -0500259} // namespace pldm