blob: 95f8adfc4f2a93ad185946920140b55694d7a654 [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
7#include <sdeventplus/event.hpp>
8#include <sdeventplus/source/event.hpp>
9
10#include <fstream>
11
12namespace pldm
13{
14
15namespace fw_update
16{
17
18class UpdateManager;
19
20/** @class DeviceUpdater
21 *
22 * DeviceUpdater orchestrates the firmware update of the firmware device and
23 * updates the UpdateManager about the status once it is complete.
24 */
25class DeviceUpdater
26{
27 public:
28 DeviceUpdater() = delete;
29 DeviceUpdater(const DeviceUpdater&) = delete;
30 DeviceUpdater(DeviceUpdater&&) = default;
31 DeviceUpdater& operator=(const DeviceUpdater&) = delete;
32 DeviceUpdater& operator=(DeviceUpdater&&) = default;
33 ~DeviceUpdater() = default;
34
35 /** @brief Constructor
36 *
37 * @param[in] eid - Endpoint ID of the firmware device
38 * @param[in] event - PLDM daemon's main event loop
39 * @param[in] requester - Instance ID manager for PLDM requests
40 * @param[in] handler - PLDM request handler
41 * @param[in] package - File stream for firmware update package
42 * @param[in] fwDeviceIDRecord - FirmwareDeviceIDRecord in the fw update
43 * package that matches this firmware device
44 * @param[in] compImageInfos - Component image information for all the
45 * components in the fw update package
46 * @param[in] compInfo - Component info for the components in this FD
47 * derived from GetFirmwareParameters response
48 * @param[in] maxTransferSize - Maximum size in bytes of the variable
49 * payload allowed to be requested by the FD
50 * @param[in] updateManager - To update the status of fw update of the
51 * device
52 */
53 explicit DeviceUpdater(
54 mctp_eid_t eid, sdeventplus::Event& event,
55 pldm::dbus_api::Requester& requester,
56 pldm::requester::Handler<pldm::requester::Request>& handler,
57 std::ifstream& package, const FirmwareDeviceIDRecord& fwDeviceIDRecord,
58 const ComponentImageInfos& compImageInfos,
59 const ComponentInfo& compInfo, uint32_t maxTransferSize,
60 UpdateManager* updateManager) :
61 eid(eid),
62 event(event), requester(requester), handler(handler), package(package),
63 fwDeviceIDRecord(fwDeviceIDRecord), compImageInfos(compImageInfos),
64 compInfo(compInfo), maxTransferSize(maxTransferSize),
65 updateManager(updateManager)
66 {}
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);
162
163 private:
164 /** @brief Send PassComponentTable command request
165 *
166 * @param[in] compOffset - component offset in compImageInfos
167 */
168 void sendPassCompTableRequest(size_t offset);
169
170 /** @brief Send UpdateComponent command request
171 *
172 * @param[in] compOffset - component offset in compImageInfos
173 */
174 void sendUpdateComponentRequest(size_t offset);
175
176 /** @brief Send ActivateFirmware command request */
177 void sendActivateFirmwareRequest();
178
179 /** @brief Endpoint ID of the firmware device */
180 mctp_eid_t eid;
181
182 /** @brief PLDM daemon's main event loop */
183 sdeventplus::Event& event;
184
185 /** @brief Instance ID manager for PLDM requests */
186 pldm::dbus_api::Requester& requester;
187
188 /** @brief PLDM request handler */
189 pldm::requester::Handler<pldm::requester::Request>& handler;
190
191 /** @brief File stream for firmware update package */
192 std::ifstream& package;
193
194 /** @brief FirmwareDeviceIDRecord in the fw update package that matches this
195 * firmware device
196 */
197 const FirmwareDeviceIDRecord& fwDeviceIDRecord;
198
199 /** @brief Component image information for all the components in the fw
200 * update package
201 */
202 const ComponentImageInfos& compImageInfos;
203
204 /** @brief Component info for the components in this FD derived from
205 * GetFirmwareParameters response
206 */
207 const ComponentInfo& compInfo;
208
209 /** @brief Maximum size in bytes of the variable payload to be requested by
210 * the FD via RequestFirmwareData command
211 */
212 uint32_t maxTransferSize;
213
214 /** @brief To update the status of fw update of the FD */
215 UpdateManager* updateManager;
216
217 /** @brief Component index is used to track the current component being
218 * updated if multiple components are applicable for the FD.
219 * It is also used to keep track of the next component in
220 * PassComponentTable
221 */
222 size_t componentIndex = 0;
223
224 /** @brief To send a PLDM request after the current command handling */
225 std::unique_ptr<sdeventplus::source::Defer> pldmRequest;
226};
227
228} // namespace fw_update
229
230} // namespace pldm