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