xref: /openbmc/pldm/fw-update/device_updater.hpp (revision 423e8f53)
1 #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 
12 namespace pldm
13 {
14 
15 namespace fw_update
16 {
17 
18 class 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  */
25 class 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&&) = delete;
33     ~DeviceUpdater() = default;
34 
35     /** @brief Constructor
36      *
37      *  @param[in] eid - Endpoint ID of the firmware device
38      *  @param[in] package - File stream for firmware update package
39      *  @param[in] fwDeviceIDRecord - FirmwareDeviceIDRecord in the fw update
40      *                                package that matches this firmware device
41      *  @param[in] compImageInfos - Component image information for all the
42      *                              components in the fw update package
43      *  @param[in] compInfo - Component info for the components in this FD
44      *                        derived from GetFirmwareParameters response
45      *  @param[in] maxTransferSize - Maximum size in bytes of the variable
46      *                               payload allowed to be requested by the FD
47      *  @param[in] updateManager - To update the status of fw update of the
48      *                             device
49      */
50     explicit DeviceUpdater(mctp_eid_t eid, std::ifstream& package,
51                            const FirmwareDeviceIDRecord& fwDeviceIDRecord,
52                            const ComponentImageInfos& compImageInfos,
53                            const ComponentInfo& compInfo,
54                            uint32_t maxTransferSize,
55                            UpdateManager* updateManager) :
56         eid(eid), package(package), fwDeviceIDRecord(fwDeviceIDRecord),
57         compImageInfos(compImageInfos), compInfo(compInfo),
58         maxTransferSize(maxTransferSize), updateManager(updateManager)
59     {}
60 
61     /** @brief Start the firmware update flow for the FD
62      *
63      *  To start the update flow RequestUpdate command is sent to the FD.
64      *
65      */
66     void startFwUpdateFlow();
67 
68     /** @brief Handler for RequestUpdate command response
69      *
70      *  The response of the RequestUpdate is processed and if the response
71      *  is success, send PassComponentTable request to FD.
72      *
73      *  @param[in] eid - Remote MCTP endpoint
74      *  @param[in] response - PLDM response message
75      *  @param[in] respMsgLen - Response message length
76      */
77     void requestUpdate(mctp_eid_t eid, const pldm_msg* response,
78                        size_t respMsgLen);
79 
80     /** @brief Handler for PassComponentTable command response
81      *
82      *  The response of the PassComponentTable is processed. If the response
83      *  indicates component can be updated, continue with either a) or b).
84      *
85      *  a. Send PassComponentTable request for the next component if
86      *     applicable
87      *  b. UpdateComponent command to request updating a specific
88      *     firmware component
89      *
90      *  If the response indicates component may be updateable, continue
91      *  based on the policy in DeviceUpdateOptionFlags.
92      *
93      *  @param[in] eid - Remote MCTP endpoint
94      *  @param[in] response - PLDM response message
95      *  @param[in] respMsgLen - Response message length
96      */
97     void passCompTable(mctp_eid_t eid, const pldm_msg* response,
98                        size_t respMsgLen);
99 
100     /** @brief Handler for UpdateComponent command response
101      *
102      *  The response of the UpdateComponent is processed and will wait for
103      *  FD to request the firmware data.
104      *
105      *  @param[in] eid - Remote MCTP endpoint
106      *  @param[in] response - PLDM response message
107      *  @param[in] respMsgLen - Response message length
108      */
109     void updateComponent(mctp_eid_t eid, const pldm_msg* response,
110                          size_t respMsgLen);
111 
112     /** @brief Handler for RequestFirmwareData request
113      *
114      *  @param[in] request - Request message
115      *  @param[in] payload_length - Request message payload length
116      *  @return Response - PLDM Response message
117      */
118     Response requestFwData(const pldm_msg* request, size_t payloadLength);
119 
120     /** @brief Handler for TransferComplete request
121      *
122      *  @param[in] request - Request message
123      *  @param[in] payload_length - Request message payload length
124      *  @return Response - PLDM Response message
125      */
126     Response transferComplete(const pldm_msg* request, size_t payloadLength);
127 
128     /** @brief Handler for VerifyComplete request
129      *
130      *  @param[in] request - Request message
131      *  @param[in] payload_length - Request message payload length
132      *  @return Response - PLDM Response message
133      */
134     Response verifyComplete(const pldm_msg* request, size_t payloadLength);
135 
136     /** @brief Handler for ApplyComplete request
137      *
138      *  @param[in] request - Request message
139      *  @param[in] payload_length - Request message payload length
140      *  @return Response - PLDM Response message
141      */
142     Response applyComplete(const pldm_msg* request, size_t payloadLength);
143 
144     /** @brief Handler for ActivateFirmware command response
145      *
146      *  The response of the ActivateFirmware is processed and will update the
147      *  UpdateManager with the completion of the firmware update.
148      *
149      *  @param[in] eid - Remote MCTP endpoint
150      *  @param[in] response - PLDM response message
151      *  @param[in] respMsgLen - Response message length
152      */
153     void activateFirmware(mctp_eid_t eid, const pldm_msg* response,
154                           size_t respMsgLen);
155 
156   private:
157     /** @brief Send PassComponentTable command request
158      *
159      *  @param[in] compOffset - component offset in compImageInfos
160      */
161     void sendPassCompTableRequest(size_t offset);
162 
163     /** @brief Send UpdateComponent command request
164      *
165      *  @param[in] compOffset - component offset in compImageInfos
166      */
167     void sendUpdateComponentRequest(size_t offset);
168 
169     /** @brief Send ActivateFirmware command request */
170     void sendActivateFirmwareRequest();
171 
172     /** @brief Endpoint ID of the firmware device */
173     mctp_eid_t eid;
174 
175     /** @brief File stream for firmware update package */
176     std::ifstream& package;
177 
178     /** @brief FirmwareDeviceIDRecord in the fw update package that matches this
179      *         firmware device
180      */
181     const FirmwareDeviceIDRecord& fwDeviceIDRecord;
182 
183     /** @brief Component image information for all the components in the fw
184      *         update package
185      */
186     const ComponentImageInfos& compImageInfos;
187 
188     /** @brief Component info for the components in this FD derived from
189      *         GetFirmwareParameters response
190      */
191     const ComponentInfo& compInfo;
192 
193     /** @brief Maximum size in bytes of the variable payload to be requested by
194      *         the FD via RequestFirmwareData command
195      */
196     uint32_t maxTransferSize;
197 
198     /** @brief To update the status of fw update of the FD */
199     UpdateManager* updateManager;
200 
201     /** @brief Component index is used to track the current component being
202      *         updated if multiple components are applicable for the FD.
203      *         It is also used to keep track of the next component in
204      *         PassComponentTable
205      */
206     size_t componentIndex = 0;
207 
208     /** @brief To send a PLDM request after the current command handling */
209     std::unique_ptr<sdeventplus::source::Defer> pldmRequest;
210 };
211 
212 } // namespace fw_update
213 
214 } // namespace pldm
215